Compare commits
29 Commits
v1.8.1-rc.
...
feat/delet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5103477e7b | ||
|
|
b19b57dbc9 | ||
|
|
2b3ab9a3b7 | ||
|
|
cac262fcea | ||
|
|
0cd7c25718 | ||
|
|
79eec5f451 | ||
|
|
7ca0975650 | ||
|
|
870b3fb3d7 | ||
|
|
43ea76fae3 | ||
|
|
2dd122aed3 | ||
|
|
d3872e86f1 | ||
|
|
171398ae2d | ||
|
|
492350612e | ||
|
|
f9935adb57 | ||
|
|
d2b99303f9 | ||
|
|
d33bbe71e7 | ||
|
|
6bf62e0ecb | ||
|
|
16527f01e7 | ||
|
|
7f25508c3c | ||
|
|
754e9e6428 | ||
|
|
2837b178fb | ||
|
|
26ccdc1b23 | ||
|
|
ea63b45a13 | ||
|
|
feef4b1a12 | ||
|
|
1a55f4253b | ||
|
|
8311e0cc29 | ||
|
|
a9adc36732 | ||
|
|
73e375938c | ||
|
|
c6393b7a9e |
@@ -139,6 +139,3 @@ E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
|||||||
# [[REDIS]]
|
# [[REDIS]]
|
||||||
NEXT_PRIVATE_REDIS_URL=
|
NEXT_PRIVATE_REDIS_URL=
|
||||||
NEXT_PRIVATE_REDIS_TOKEN=
|
NEXT_PRIVATE_REDIS_TOKEN=
|
||||||
|
|
||||||
# [[LOGGER]]
|
|
||||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"index": "Get Started",
|
|
||||||
"react": "React Integration",
|
|
||||||
"vue": "Vue Integration",
|
|
||||||
"svelte": "Svelte Integration",
|
|
||||||
"solid": "Solid Integration",
|
|
||||||
"preact": "Preact Integration",
|
|
||||||
"css-variables": "CSS Variables"
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
---
|
|
||||||
title: CSS Variables
|
|
||||||
description: Learn about all available CSS variables for customizing your embedded signing experience
|
|
||||||
---
|
|
||||||
|
|
||||||
# CSS Variables
|
|
||||||
|
|
||||||
Platform customers have access to a comprehensive set of CSS variables that can be used to customize the appearance of the embedded signing experience. These variables control everything from colors to spacing and can be used to match your application's design system.
|
|
||||||
|
|
||||||
## Available Variables
|
|
||||||
|
|
||||||
### Colors
|
|
||||||
|
|
||||||
| Variable | Description | Default |
|
|
||||||
| ----------------------- | ---------------------------------- | -------------- |
|
|
||||||
| `background` | Base background color | System default |
|
|
||||||
| `foreground` | Base text color | System default |
|
|
||||||
| `muted` | Muted/subtle background color | System default |
|
|
||||||
| `mutedForeground` | Muted/subtle text color | System default |
|
|
||||||
| `popover` | Popover/dropdown background color | System default |
|
|
||||||
| `popoverForeground` | Popover/dropdown text color | System default |
|
|
||||||
| `card` | Card background color | System default |
|
|
||||||
| `cardBorder` | Card border color | System default |
|
|
||||||
| `cardBorderTint` | Card border tint/highlight color | System default |
|
|
||||||
| `cardForeground` | Card text color | System default |
|
|
||||||
| `fieldCard` | Field card background color | System default |
|
|
||||||
| `fieldCardBorder` | Field card border color | System default |
|
|
||||||
| `fieldCardForeground` | Field card text color | System default |
|
|
||||||
| `widget` | Widget background color | System default |
|
|
||||||
| `widgetForeground` | Widget text color | System default |
|
|
||||||
| `border` | Default border color | System default |
|
|
||||||
| `input` | Input field border color | System default |
|
|
||||||
| `primary` | Primary action/button color | System default |
|
|
||||||
| `primaryForeground` | Primary action/button text color | System default |
|
|
||||||
| `secondary` | Secondary action/button color | System default |
|
|
||||||
| `secondaryForeground` | Secondary action/button text color | System default |
|
|
||||||
| `accent` | Accent/highlight color | System default |
|
|
||||||
| `accentForeground` | Accent/highlight text color | System default |
|
|
||||||
| `destructive` | Destructive/danger action color | System default |
|
|
||||||
| `destructiveForeground` | Destructive/danger text color | System default |
|
|
||||||
| `ring` | Focus ring color | System default |
|
|
||||||
| `warning` | Warning/alert color | System default |
|
|
||||||
|
|
||||||
### Spacing and Layout
|
|
||||||
|
|
||||||
| Variable | Description | Default |
|
|
||||||
| -------- | ------------------------------- | -------------- |
|
|
||||||
| `radius` | Border radius size in REM units | System default |
|
|
||||||
|
|
||||||
## Usage Example
|
|
||||||
|
|
||||||
Here's how to use these variables in your embedding implementation:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
const cssVars = {
|
|
||||||
// Colors
|
|
||||||
background: '#ffffff',
|
|
||||||
foreground: '#000000',
|
|
||||||
primary: '#0000ff',
|
|
||||||
primaryForeground: '#ffffff',
|
|
||||||
accent: '#4f46e5',
|
|
||||||
destructive: '#ef4444',
|
|
||||||
|
|
||||||
// Spacing
|
|
||||||
radius: '0.5rem'
|
|
||||||
};
|
|
||||||
|
|
||||||
// React/Preact
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
token={token}
|
|
||||||
cssVars={cssVars}
|
|
||||||
/>
|
|
||||||
|
|
||||||
// Vue
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
:token="token"
|
|
||||||
:cssVars="cssVars"
|
|
||||||
/>
|
|
||||||
|
|
||||||
// Svelte
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
{token}
|
|
||||||
cssVars={cssVars}
|
|
||||||
/>
|
|
||||||
|
|
||||||
// Solid
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
token={token}
|
|
||||||
cssVars={cssVars}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Color Format
|
|
||||||
|
|
||||||
Colors can be specified in any valid CSS color format:
|
|
||||||
|
|
||||||
- Hexadecimal: `#ff0000`
|
|
||||||
- RGB: `rgb(255, 0, 0)`
|
|
||||||
- HSL: `hsl(0, 100%, 50%)`
|
|
||||||
- Named colors: `red`
|
|
||||||
|
|
||||||
The colors will be automatically converted to the appropriate format internally.
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
1. **Maintain Contrast**: When customizing colors, ensure there's sufficient contrast between background and foreground colors for accessibility.
|
|
||||||
|
|
||||||
2. **Test Dark Mode**: If you haven't disabled dark mode, test your color variables in both light and dark modes.
|
|
||||||
|
|
||||||
3. **Use Your Brand Colors**: Align the primary and accent colors with your brand's color scheme for a cohesive look.
|
|
||||||
|
|
||||||
4. **Consistent Radius**: Use a consistent border radius value that matches your application's design system.
|
|
||||||
|
|
||||||
## Related
|
|
||||||
|
|
||||||
- [React Integration](/developers/embedding/react)
|
|
||||||
- [Vue Integration](/developers/embedding/vue)
|
|
||||||
- [Svelte Integration](/developers/embedding/svelte)
|
|
||||||
- [Solid Integration](/developers/embedding/solid)
|
|
||||||
- [Preact Integration](/developers/embedding/preact)
|
|
||||||
@@ -11,11 +11,7 @@ Our embedding feature lets you integrate our document signing experience into yo
|
|||||||
|
|
||||||
Embedding is currently available for all users on a **Teams Plan** and above, as well as **Early Adopter's** within a team (Early Adopters can create a team for free).
|
Embedding is currently available for all users on a **Teams Plan** and above, as well as **Early Adopter's** within a team (Early Adopters can create a team for free).
|
||||||
|
|
||||||
Our **Platform Plan** offers enhanced customization features including:
|
In the future, we will roll out a **Platform Plan** that will offer additional enhancements for embedding, including the option to remove Documenso branding for a more customized experience.
|
||||||
|
|
||||||
- Custom CSS and styling variables
|
|
||||||
- Dark mode controls
|
|
||||||
- The removal of Documenso branding from the embedding experience
|
|
||||||
|
|
||||||
## How Embedding Works
|
## How Embedding Works
|
||||||
|
|
||||||
@@ -26,49 +22,6 @@ Embedding with Documenso allows you to handle document signing in two main ways:
|
|||||||
|
|
||||||
_For most use-cases we recommend using direct templates, however if you have a need for a more advanced integration, we are happy to help you get started._
|
_For most use-cases we recommend using direct templates, however if you have a need for a more advanced integration, we are happy to help you get started._
|
||||||
|
|
||||||
## Customization Options
|
|
||||||
|
|
||||||
### Styling and Theming
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options to customize the embedding experience:
|
|
||||||
|
|
||||||
1. **Custom CSS**: You can provide custom CSS to style the embedded component:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
token={token}
|
|
||||||
css={`
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **CSS Variables**: Fine-tune the appearance using CSS variables for colors, spacing, and more:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
token={token}
|
|
||||||
cssVars={{
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
For a complete list of available CSS variables and their usage, see our [CSS Variables](/developers/embedding/css-variables) documentation.
|
|
||||||
|
|
||||||
3. **Dark Mode Control**: Disable dark mode if it doesn't match your application's theme:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<EmbedDirectTemplate token={token} darkModeDisabled={true} />
|
|
||||||
```
|
|
||||||
|
|
||||||
These customization options are available for both Direct Templates and Signing Token embeds.
|
|
||||||
|
|
||||||
## Supported Frameworks
|
## Supported Frameworks
|
||||||
|
|
||||||
We support embedding across a range of popular JavaScript frameworks, including:
|
We support embedding across a range of popular JavaScript frameworks, including:
|
||||||
@@ -167,11 +120,12 @@ Once you've obtained the appropriate tokens, you can integrate the signing exper
|
|||||||
|
|
||||||
If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases.
|
If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases.
|
||||||
|
|
||||||
## Related
|
## Stay Tuned for the Platform Plan
|
||||||
|
|
||||||
- [React Integration](/developers/embedding/react)
|
While embedding is already a powerful tool, we're working on a **Platform Plan** that will introduce even more functionality. This plan will offer:
|
||||||
- [Vue Integration](/developers/embedding/vue)
|
|
||||||
- [Svelte Integration](/developers/embedding/svelte)
|
- Additional customization options
|
||||||
- [Solid Integration](/developers/embedding/solid)
|
- The ability to remove Documenso branding
|
||||||
- [Preact Integration](/developers/embedding/preact)
|
- Additional controls for the signing experience
|
||||||
- [CSS Variables](/developers/embedding/css-variables)
|
|
||||||
|
More details will be shared as we approach the release.
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ const MyEmbeddingComponent = () => {
|
|||||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||||
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
||||||
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
|
|
||||||
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
|
|
||||||
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
|
|
||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
@@ -78,30 +75,3 @@ const MyEmbeddingComponent = () => {
|
|||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
|
|
||||||
### Styling and Theming (Platform Plan)
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { EmbedDirectTemplate } from '@documenso/embed-preact';
|
|
||||||
|
|
||||||
const MyEmbeddingComponent = () => {
|
|
||||||
const token = 'your-token';
|
|
||||||
const customCss = `
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
const cssVars = {
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ const MyEmbeddingComponent = () => {
|
|||||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||||
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
||||||
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
|
|
||||||
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
|
|
||||||
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
|
|
||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
@@ -78,34 +75,3 @@ const MyEmbeddingComponent = () => {
|
|||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
|
|
||||||
### Styling and Theming (Platform Plan)
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { EmbedDirectTemplate } from '@documenso/embed-react';
|
|
||||||
|
|
||||||
const MyEmbeddingComponent = () => {
|
|
||||||
return (
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
token="your-token"
|
|
||||||
// Custom CSS
|
|
||||||
css={`
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
// CSS Variables
|
|
||||||
cssVars={{
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
}}
|
|
||||||
// Dark Mode Control
|
|
||||||
darkModeDisabled={true}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ const MyEmbeddingComponent = () => {
|
|||||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||||
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
||||||
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
|
|
||||||
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
|
|
||||||
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
|
|
||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
@@ -78,30 +75,3 @@ const MyEmbeddingComponent = () => {
|
|||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
|
|
||||||
### Styling and Theming (Platform Plan)
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import { EmbedDirectTemplate } from '@documenso/embed-solid';
|
|
||||||
|
|
||||||
const MyEmbeddingComponent = () => {
|
|
||||||
const token = 'your-token';
|
|
||||||
const customCss = `
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
const cssVars = {
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -46,9 +46,6 @@ If you have a direct link template, you can simply provide the token for the tem
|
|||||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||||
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
||||||
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
|
|
||||||
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
|
|
||||||
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
|
|
||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
@@ -80,28 +77,3 @@ const MyEmbeddingComponent = () => {
|
|||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
|
|
||||||
### Styling and Theming (Platform Plan)
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script lang="ts">
|
|
||||||
import { EmbedDirectTemplate } from '@documenso/embed-svelte';
|
|
||||||
|
|
||||||
const token = 'your-token';
|
|
||||||
const customCss = `
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
const cssVars = {
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<EmbedDirectTemplate {token} css="{customCss}" cssVars="{cssVars}" darkModeDisabled="{true}" />
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -46,9 +46,6 @@ If you have a direct link template, you can simply provide the token for the tem
|
|||||||
| email | string (optional) | The email the signer that will be used by default for signing |
|
| email | string (optional) | The email the signer that will be used by default for signing |
|
||||||
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
|
||||||
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
|
||||||
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
|
|
||||||
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
|
|
||||||
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
|
|
||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
@@ -80,35 +77,3 @@ const MyEmbeddingComponent = () => {
|
|||||||
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
|
||||||
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
|
||||||
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
|
||||||
|
|
||||||
### Styling and Theming (Platform Plan)
|
|
||||||
|
|
||||||
Platform customers have access to advanced styling options:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { EmbedDirectTemplate } from '@documenso/embed-vue';
|
|
||||||
|
|
||||||
const token = ref('your-token');
|
|
||||||
const customCss = `
|
|
||||||
.documenso-embed {
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
const cssVars = {
|
|
||||||
colorPrimary: '#0000FF',
|
|
||||||
colorBackground: '#F5F5F5',
|
|
||||||
borderRadius: '8px',
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<EmbedDirectTemplate
|
|
||||||
:token="token"
|
|
||||||
:css="customCss"
|
|
||||||
:cssVars="cssVars"
|
|
||||||
:darkModeDisabled="true"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@documenso/marketing",
|
"name": "@documenso/marketing",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
2
apps/marketing/process-env.d.ts
vendored
2
apps/marketing/process-env.d.ts
vendored
@@ -2,7 +2,7 @@ declare namespace NodeJS {
|
|||||||
export interface ProcessEnv {
|
export interface ProcessEnv {
|
||||||
NEXT_PUBLIC_WEBAPP_URL?: string;
|
NEXT_PUBLIC_WEBAPP_URL?: string;
|
||||||
NEXT_PUBLIC_MARKETING_URL?: string;
|
NEXT_PUBLIC_MARKETING_URL?: string;
|
||||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string;
|
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?: string;
|
||||||
|
|
||||||
NEXT_PRIVATE_DATABASE_URL: string;
|
NEXT_PRIVATE_DATABASE_URL: string;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@documenso/web",
|
"name": "@documenso/web",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
2
apps/web/process-env.d.ts
vendored
2
apps/web/process-env.d.ts
vendored
@@ -2,7 +2,7 @@ declare namespace NodeJS {
|
|||||||
export interface ProcessEnv {
|
export interface ProcessEnv {
|
||||||
NEXT_PUBLIC_WEBAPP_URL?: string;
|
NEXT_PUBLIC_WEBAPP_URL?: string;
|
||||||
NEXT_PUBLIC_MARKETING_URL?: string;
|
NEXT_PUBLIC_MARKETING_URL?: string;
|
||||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string;
|
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?: string;
|
||||||
|
|
||||||
NEXT_PRIVATE_DATABASE_URL: string;
|
NEXT_PRIVATE_DATABASE_URL: string;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const DocumentPageViewInformation = ({
|
|||||||
const { _, i18n } = useLingui();
|
const { _, i18n } = useLingui();
|
||||||
|
|
||||||
const documentInformation = useMemo(() => {
|
const documentInformation = useMemo(() => {
|
||||||
return [
|
const info = [
|
||||||
{
|
{
|
||||||
description: msg`Uploaded by`,
|
description: msg`Uploaded by`,
|
||||||
value: userId === document.userId ? _(msg`You`) : document.User.name ?? document.User.email,
|
value: userId === document.userId ? _(msg`You`) : document.User.name ?? document.User.email,
|
||||||
@@ -44,8 +44,20 @@ export const DocumentPageViewInformation = ({
|
|||||||
.toRelative(),
|
.toRelative(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [isMounted, document, userId]);
|
if (document.deletedAt) {
|
||||||
|
info.push({
|
||||||
|
description: msg`Deleted`,
|
||||||
|
value:
|
||||||
|
document.deletedAt &&
|
||||||
|
DateTime.fromJSDate(document.deletedAt)
|
||||||
|
.setLocale(i18n.locales?.[0] || i18n.locale)
|
||||||
|
.toFormat('MMMM d, yyyy'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}, [isMounted, document, i18n.locales?.[0] || i18n.locale, userId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="dark:bg-background text-foreground border-border bg-widget flex flex-col rounded-xl border">
|
<section className="dark:bg-background text-foreground border-border bg-widget flex flex-col rounded-xl border">
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
|
|||||||
<DocumentPageViewDropdown document={documentWithRecipients} team={team} />
|
<DocumentPageViewDropdown document={documentWithRecipients} team={team} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-muted-foreground mt-2 px-4 text-sm ">
|
<p className="text-muted-foreground mt-2 px-4 text-sm">
|
||||||
{match(document.status)
|
{match(document.status)
|
||||||
.with(DocumentStatus.COMPLETED, () => (
|
.with(DocumentStatus.COMPLETED, () => (
|
||||||
<Trans>This document has been signed by all recipients</Trans>
|
<Trans>This document has been signed by all recipients</Trans>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import Link from 'next/link';
|
|||||||
import { Trans, msg } from '@lingui/macro';
|
import { Trans, msg } from '@lingui/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import {
|
import {
|
||||||
|
ArchiveRestore,
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
Copy,
|
Copy,
|
||||||
Download,
|
Download,
|
||||||
@@ -23,8 +24,8 @@ import { useSession } from 'next-auth/react';
|
|||||||
|
|
||||||
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
|
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
|
||||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||||
import { DocumentStatus, RecipientRole } from '@documenso/prisma/client';
|
|
||||||
import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
|
import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
|
||||||
|
import { DocumentStatus, RecipientRole } from '@documenso/prisma/client';
|
||||||
import type { DocumentWithData } from '@documenso/prisma/types/document-with-data';
|
import type { DocumentWithData } from '@documenso/prisma/types/document-with-data';
|
||||||
import { trpc as trpcClient } from '@documenso/trpc/client';
|
import { trpc as trpcClient } from '@documenso/trpc/client';
|
||||||
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
|
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
|
||||||
@@ -43,6 +44,7 @@ import { ResendDocumentActionItem } from './_action-items/resend-document';
|
|||||||
import { DeleteDocumentDialog } from './delete-document-dialog';
|
import { DeleteDocumentDialog } from './delete-document-dialog';
|
||||||
import { DuplicateDocumentDialog } from './duplicate-document-dialog';
|
import { DuplicateDocumentDialog } from './duplicate-document-dialog';
|
||||||
import { MoveDocumentDialog } from './move-document-dialog';
|
import { MoveDocumentDialog } from './move-document-dialog';
|
||||||
|
import { RestoreDocumentDialog } from './restore-document-dialog';
|
||||||
|
|
||||||
export type DataTableActionDropdownProps = {
|
export type DataTableActionDropdownProps = {
|
||||||
row: Document & {
|
row: Document & {
|
||||||
@@ -61,6 +63,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
|
|||||||
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||||
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
|
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
|
||||||
const [isMoveDialogOpen, setMoveDialogOpen] = useState(false);
|
const [isMoveDialogOpen, setMoveDialogOpen] = useState(false);
|
||||||
|
const [isRestoreDialogOpen, setRestoreDialogOpen] = useState(false);
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return null;
|
return null;
|
||||||
@@ -76,6 +79,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
|
|||||||
// const isSigned = recipient?.signingStatus === SigningStatus.SIGNED;
|
// const isSigned = recipient?.signingStatus === SigningStatus.SIGNED;
|
||||||
const isCurrentTeamDocument = team && row.team?.url === team.url;
|
const isCurrentTeamDocument = team && row.team?.url === team.url;
|
||||||
const canManageDocument = Boolean(isOwner || isCurrentTeamDocument);
|
const canManageDocument = Boolean(isOwner || isCurrentTeamDocument);
|
||||||
|
const isDeletedDocument = row.deletedAt !== null;
|
||||||
|
|
||||||
const documentsPath = formatDocumentsPath(team?.url);
|
const documentsPath = formatDocumentsPath(team?.url);
|
||||||
|
|
||||||
@@ -181,13 +185,23 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
|
|||||||
Void
|
Void
|
||||||
</DropdownMenuItem> */}
|
</DropdownMenuItem> */}
|
||||||
|
|
||||||
|
{isDeletedDocument ? (
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => setRestoreDialogOpen(true)}
|
||||||
|
disabled={Boolean(!canManageDocument)}
|
||||||
|
>
|
||||||
|
<ArchiveRestore className="mr-2 h-4 w-4" />
|
||||||
|
Restore
|
||||||
|
</DropdownMenuItem>
|
||||||
|
) : (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => setDeleteDialogOpen(true)}
|
onClick={() => setDeleteDialogOpen(true)}
|
||||||
disabled={Boolean(!canManageDocument && team?.teamEmail)}
|
disabled={Boolean(!canManageDocument && team?.teamEmail)}
|
||||||
>
|
>
|
||||||
<Trash2 className="mr-2 h-4 w-4" />
|
<Trash2 className="mr-2 h-4 w-4" />
|
||||||
{canManageDocument ? _(msg`Delete`) : _(msg`Hide`)}
|
{canManageDocument ? 'Delete' : 'Hide'}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
<DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
<Trans>Share</Trans>
|
<Trans>Share</Trans>
|
||||||
@@ -239,6 +253,16 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
|
|||||||
onOpenChange={setMoveDialogOpen}
|
onOpenChange={setMoveDialogOpen}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<RestoreDocumentDialog
|
||||||
|
id={row.id}
|
||||||
|
status={row.status}
|
||||||
|
documentTitle={row.title}
|
||||||
|
open={isRestoreDialogOpen}
|
||||||
|
onOpenChange={setRestoreDialogOpen}
|
||||||
|
teamId={team?.id}
|
||||||
|
canManageDocument={canManageDocument}
|
||||||
|
/>
|
||||||
|
|
||||||
{isDuplicateDialogOpen && (
|
{isDuplicateDialogOpen && (
|
||||||
<DuplicateDocumentDialog
|
<DuplicateDocumentDialog
|
||||||
id={row.id}
|
id={row.id}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { Trans } from '@lingui/macro';
|
|||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
|
|
||||||
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
|
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
|
||||||
import type { GetStatsInput } from '@documenso/lib/server-only/document/get-stats';
|
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
|
||||||
import { getStats } from '@documenso/lib/server-only/document/get-stats';
|
import type { GetStatsInput } from '@documenso/lib/server-only/document/get-stats-new';
|
||||||
|
import { getStats } from '@documenso/lib/server-only/document/get-stats-new';
|
||||||
import { parseToIntegerArray } from '@documenso/lib/utils/params';
|
import { parseToIntegerArray } from '@documenso/lib/utils/params';
|
||||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||||
import type { Team, TeamEmail, TeamMemberRole } from '@documenso/prisma/client';
|
import type { Team, TeamEmail, TeamMemberRole } from '@documenso/prisma/client';
|
||||||
@@ -35,7 +35,7 @@ export interface DocumentsPageViewProps {
|
|||||||
senderIds?: string;
|
senderIds?: string;
|
||||||
search?: string;
|
search?: string;
|
||||||
};
|
};
|
||||||
team?: Team & { teamEmail?: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
|
team?: Team & { teamEmail: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPageViewProps) => {
|
export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPageViewProps) => {
|
||||||
@@ -50,25 +50,14 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
|||||||
const currentTeam = team
|
const currentTeam = team
|
||||||
? { id: team.id, url: team.url, teamEmail: team.teamEmail?.email }
|
? { id: team.id, url: team.url, teamEmail: team.teamEmail?.email }
|
||||||
: undefined;
|
: undefined;
|
||||||
const currentTeamMemberRole = team?.currentTeamMember?.role;
|
|
||||||
|
|
||||||
const getStatOptions: GetStatsInput = {
|
const getStatOptions: GetStatsInput = {
|
||||||
user,
|
user,
|
||||||
period,
|
period,
|
||||||
|
team,
|
||||||
search,
|
search,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (team) {
|
|
||||||
getStatOptions.team = {
|
|
||||||
teamId: team.id,
|
|
||||||
teamEmail: team.teamEmail?.email,
|
|
||||||
senderIds,
|
|
||||||
currentTeamMemberRole,
|
|
||||||
currentUserEmail: user.email,
|
|
||||||
userId: user.id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const stats = await getStats(getStatOptions);
|
const stats = await getStats(getStatOptions);
|
||||||
|
|
||||||
const results = await findDocuments({
|
const results = await findDocuments({
|
||||||
@@ -128,6 +117,7 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
|||||||
ExtendedDocumentStatus.PENDING,
|
ExtendedDocumentStatus.PENDING,
|
||||||
ExtendedDocumentStatus.COMPLETED,
|
ExtendedDocumentStatus.COMPLETED,
|
||||||
ExtendedDocumentStatus.DRAFT,
|
ExtendedDocumentStatus.DRAFT,
|
||||||
|
ExtendedDocumentStatus.BIN,
|
||||||
ExtendedDocumentStatus.ALL,
|
ExtendedDocumentStatus.ALL,
|
||||||
].map((value) => (
|
].map((value) => (
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { msg } from '@lingui/macro';
|
import { msg } from '@lingui/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { Bird, CheckCircle2 } from 'lucide-react';
|
import { Bird, CheckCircle2, Trash } from 'lucide-react';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||||
@@ -30,6 +30,11 @@ export const EmptyDocumentState = ({ status }: EmptyDocumentProps) => {
|
|||||||
message: msg`You have not yet created or received any documents. To create a document please upload one.`,
|
message: msg`You have not yet created or received any documents. To create a document please upload one.`,
|
||||||
icon: Bird,
|
icon: Bird,
|
||||||
}))
|
}))
|
||||||
|
.with(ExtendedDocumentStatus.BIN, () => ({
|
||||||
|
title: msg`No documents in the bin`,
|
||||||
|
message: msg`There are no documents in the bin.`,
|
||||||
|
icon: Trash,
|
||||||
|
}))
|
||||||
.otherwise(() => ({
|
.otherwise(() => ({
|
||||||
title: msg`Nothing to do`,
|
title: msg`Nothing to do`,
|
||||||
message: msg`All documents have been processed. Any new documents that are sent or received will show here.`,
|
message: msg`All documents have been processed. Any new documents that are sent or received will show here.`,
|
||||||
@@ -42,7 +47,6 @@ export const EmptyDocumentState = ({ status }: EmptyDocumentProps) => {
|
|||||||
data-testid="empty-document-state"
|
data-testid="empty-document-state"
|
||||||
>
|
>
|
||||||
<Icon className="h-12 w-12" strokeWidth={1.5} />
|
<Icon className="h-12 w-12" strokeWidth={1.5} />
|
||||||
|
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h3 className="text-lg font-semibold">{_(title)}</h3>
|
<h3 className="text-lg font-semibold">{_(title)}</h3>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
import type { DocumentStatus } from '@documenso/prisma/client';
|
||||||
|
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||||
|
import {
|
||||||
|
AlertDialog,
|
||||||
|
AlertDialogCancel,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogFooter,
|
||||||
|
AlertDialogHeader,
|
||||||
|
AlertDialogTitle,
|
||||||
|
} from '@documenso/ui/primitives/alert-dialog';
|
||||||
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||||
|
|
||||||
|
type RestoreDocumentDialogProps = {
|
||||||
|
id: number;
|
||||||
|
open: boolean;
|
||||||
|
onOpenChange: (_open: boolean) => void;
|
||||||
|
status: DocumentStatus;
|
||||||
|
documentTitle: string;
|
||||||
|
teamId?: number;
|
||||||
|
canManageDocument: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function RestoreDocumentDialog({
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
open,
|
||||||
|
onOpenChange,
|
||||||
|
documentTitle,
|
||||||
|
canManageDocument,
|
||||||
|
}: RestoreDocumentDialogProps) {
|
||||||
|
const router = useRouter();
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const { mutateAsync: restoreDocument, isLoading } =
|
||||||
|
trpcReact.document.restoreDocument.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
router.refresh();
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: 'Document restored',
|
||||||
|
description: `"${documentTitle}" has been successfully restored`,
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
|
|
||||||
|
onOpenChange(false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onRestore = async () => {
|
||||||
|
try {
|
||||||
|
await restoreDocument({ id, teamId });
|
||||||
|
} catch {
|
||||||
|
toast({
|
||||||
|
title: 'Something went wrong',
|
||||||
|
description: 'This document could not be restored at this time. Please try again.',
|
||||||
|
variant: 'destructive',
|
||||||
|
duration: 7500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AlertDialog open={open} onOpenChange={(value) => !isLoading && onOpenChange(value)}>
|
||||||
|
<AlertDialogContent>
|
||||||
|
<AlertDialogHeader>
|
||||||
|
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription>
|
||||||
|
You are about to restore the document <strong>"{documentTitle}"</strong>
|
||||||
|
</AlertDialogDescription>
|
||||||
|
</AlertDialogHeader>
|
||||||
|
<AlertDialogFooter>
|
||||||
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
loading={isLoading}
|
||||||
|
onClick={onRestore}
|
||||||
|
disabled={!canManageDocument}
|
||||||
|
>
|
||||||
|
Restore
|
||||||
|
</Button>
|
||||||
|
</AlertDialogFooter>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -53,17 +53,6 @@ export const SigningPageView = ({
|
|||||||
}: SigningPageViewProps) => {
|
}: SigningPageViewProps) => {
|
||||||
const { documentData, documentMeta } = document;
|
const { documentData, documentMeta } = document;
|
||||||
|
|
||||||
const shouldUseTeamDetails =
|
|
||||||
document.teamId && document.team?.teamGlobalSettings?.includeSenderDetails === false;
|
|
||||||
|
|
||||||
let senderName = document.User.name ?? '';
|
|
||||||
let senderEmail = `(${document.User.email})`;
|
|
||||||
|
|
||||||
if (shouldUseTeamDetails) {
|
|
||||||
senderName = document.team?.name ?? '';
|
|
||||||
senderEmail = document.team?.teamEmail?.email ? `(${document.team.teamEmail.email})` : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full max-w-screen-xl">
|
<div className="mx-auto w-full max-w-screen-xl">
|
||||||
<h1
|
<h1
|
||||||
@@ -74,41 +63,27 @@ export const SigningPageView = ({
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div className="mt-2.5 flex flex-wrap items-center justify-between gap-x-6">
|
<div className="mt-2.5 flex flex-wrap items-center justify-between gap-x-6">
|
||||||
<div className="max-w-[50ch]">
|
<div>
|
||||||
<span className="text-muted-foreground truncate" title={senderName}>
|
<p
|
||||||
{senderName} {senderEmail}
|
className="text-muted-foreground truncate"
|
||||||
</span>{' '}
|
title={document.User.name ? document.User.name : ''}
|
||||||
<span className="text-muted-foreground">
|
>
|
||||||
|
{document.User.name}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-muted-foreground">
|
||||||
{match(recipient.role)
|
{match(recipient.role)
|
||||||
.with(RecipientRole.VIEWER, () =>
|
.with(RecipientRole.VIEWER, () => (
|
||||||
document.teamId && !shouldUseTeamDetails ? (
|
<Trans>({document.User.email}) has invited you to view this document</Trans>
|
||||||
<Trans>
|
))
|
||||||
on behalf of "{document.team?.name}" has invited you to view this document
|
.with(RecipientRole.SIGNER, () => (
|
||||||
</Trans>
|
<Trans>({document.User.email}) has invited you to sign this document</Trans>
|
||||||
) : (
|
))
|
||||||
<Trans>has invited you to view this document</Trans>
|
.with(RecipientRole.APPROVER, () => (
|
||||||
),
|
<Trans>({document.User.email}) has invited you to approve this document</Trans>
|
||||||
)
|
))
|
||||||
.with(RecipientRole.SIGNER, () =>
|
|
||||||
document.teamId && !shouldUseTeamDetails ? (
|
|
||||||
<Trans>
|
|
||||||
on behalf of "{document.team?.name}" has invited you to sign this document
|
|
||||||
</Trans>
|
|
||||||
) : (
|
|
||||||
<Trans>has invited you to sign this document</Trans>
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.with(RecipientRole.APPROVER, () =>
|
|
||||||
document.teamId && !shouldUseTeamDetails ? (
|
|
||||||
<Trans>
|
|
||||||
on behalf of "{document.team?.name}" has invited you to approve this document
|
|
||||||
</Trans>
|
|
||||||
) : (
|
|
||||||
<Trans>has invited you to approve this document</Trans>
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.otherwise(() => null)}
|
.otherwise(() => null)}
|
||||||
</span>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RejectDocumentDialog document={document} token={recipient.token} />
|
<RejectDocumentDialog document={document} token={recipient.token} />
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ export const DocumentHistorySheet = ({
|
|||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED },
|
||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED },
|
||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED },
|
||||||
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED },
|
||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED },
|
||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED },
|
||||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED },
|
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED },
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'react';
|
|||||||
import type { MessageDescriptor } from '@lingui/core';
|
import type { MessageDescriptor } from '@lingui/core';
|
||||||
import { msg } from '@lingui/macro';
|
import { msg } from '@lingui/macro';
|
||||||
import { useLingui } from '@lingui/react';
|
import { useLingui } from '@lingui/react';
|
||||||
import { CheckCircle2, Clock, File } from 'lucide-react';
|
import { CheckCircle2, Clock, File, TrashIcon } from 'lucide-react';
|
||||||
import type { LucideIcon } from 'lucide-react/dist/lucide-react';
|
import type { LucideIcon } from 'lucide-react/dist/lucide-react';
|
||||||
|
|
||||||
import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||||
@@ -47,6 +47,12 @@ export const FRIENDLY_STATUS_MAP: Record<ExtendedDocumentStatus, FriendlyStatus>
|
|||||||
labelExtended: msg`Document All`,
|
labelExtended: msg`Document All`,
|
||||||
color: 'text-muted-foreground',
|
color: 'text-muted-foreground',
|
||||||
},
|
},
|
||||||
|
BIN: {
|
||||||
|
label: msg`Bin`,
|
||||||
|
labelExtended: msg`Document Bin`,
|
||||||
|
icon: TrashIcon,
|
||||||
|
color: 'text-red-500 dark:text-red-200',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DocumentStatusProps = HTMLAttributes<HTMLSpanElement> & {
|
export type DocumentStatusProps = HTMLAttributes<HTMLSpanElement> & {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
|
||||||
import { buildLogger } from '@documenso/lib/utils/logger';
|
|
||||||
import * as trpcNext from '@documenso/trpc/server/adapters/next';
|
import * as trpcNext from '@documenso/trpc/server/adapters/next';
|
||||||
import { createTrpcContext } from '@documenso/trpc/server/context';
|
import { createTrpcContext } from '@documenso/trpc/server/context';
|
||||||
import { appRouter } from '@documenso/trpc/server/router';
|
import { appRouter } from '@documenso/trpc/server/router';
|
||||||
@@ -13,44 +11,7 @@ export const config = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const logger = buildLogger();
|
|
||||||
|
|
||||||
export default trpcNext.createNextApiHandler({
|
export default trpcNext.createNextApiHandler({
|
||||||
router: appRouter,
|
router: appRouter,
|
||||||
createContext: async ({ req, res }) => createTrpcContext({ req, res }),
|
createContext: async ({ req, res }) => createTrpcContext({ req, res }),
|
||||||
onError(opts) {
|
|
||||||
const { error, path } = opts;
|
|
||||||
|
|
||||||
// Currently trialing changes with template and team router only.
|
|
||||||
if (!path || (!path.startsWith('template') && !path.startsWith('team'))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always log the error for now.
|
|
||||||
console.error(error);
|
|
||||||
|
|
||||||
const appError = AppError.parseError(error.cause || error);
|
|
||||||
|
|
||||||
const isAppError = error.cause instanceof AppError;
|
|
||||||
|
|
||||||
// Only log AppErrors that are explicitly set to 500 or the error code
|
|
||||||
// is in the errorCodesToAlertOn list.
|
|
||||||
const isLoggableAppError =
|
|
||||||
isAppError && (appError.statusCode === 500 || errorCodesToAlertOn.includes(appError.code));
|
|
||||||
|
|
||||||
// Only log TRPC errors that are in the `errorCodesToAlertOn` list and is
|
|
||||||
// not an AppError.
|
|
||||||
const isLoggableTrpcError = !isAppError && errorCodesToAlertOn.includes(error.code);
|
|
||||||
|
|
||||||
if (isLoggableAppError || isLoggableTrpcError) {
|
|
||||||
logger.error(error, {
|
|
||||||
method: path,
|
|
||||||
context: {
|
|
||||||
appError: AppError.toJSON(appError),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorCodesToAlertOn = [AppErrorCode.UNKNOWN_ERROR, 'INTERNAL_SERVER_ERROR'];
|
|
||||||
|
|||||||
144
package-lock.json
generated
144
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@documenso/root",
|
"name": "@documenso/root",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@documenso/root",
|
"name": "@documenso/root",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
"packages/*"
|
"packages/*"
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
},
|
},
|
||||||
"apps/marketing": {
|
"apps/marketing": {
|
||||||
"name": "@documenso/marketing",
|
"name": "@documenso/marketing",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@documenso/assets": "*",
|
"@documenso/assets": "*",
|
||||||
@@ -438,7 +438,7 @@
|
|||||||
},
|
},
|
||||||
"apps/web": {
|
"apps/web": {
|
||||||
"name": "@documenso/web",
|
"name": "@documenso/web",
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@documenso/api": "*",
|
"@documenso/api": "*",
|
||||||
@@ -3498,34 +3498,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
|
"resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
|
||||||
"integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw=="
|
"integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw=="
|
||||||
},
|
},
|
||||||
"node_modules/@honeybadger-io/core": {
|
|
||||||
"version": "6.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/core/-/core-6.6.0.tgz",
|
|
||||||
"integrity": "sha512-B5X05huAsDs7NJOYm4bwHf2v0tMuTjBWLfumHH9DCblq8E1XrujlbbNkIdEHlzc01K9oAXuvsaBwVkE7G5+aLQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"json-nd": "^1.0.0",
|
|
||||||
"stacktrace-parser": "^0.1.10"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@honeybadger-io/js": {
|
|
||||||
"version": "6.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/js/-/js-6.10.1.tgz",
|
|
||||||
"integrity": "sha512-T5WAhYHWHXFMxjY4NSawSY945i8ISIL5/gsjN3m0xO+oXrBAFaul3wY5p/FGH6r6RfCrjHoHl9Iu7Ed9aO9Ehg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@honeybadger-io/core": "^6.6.0",
|
|
||||||
"@types/aws-lambda": "^8.10.89",
|
|
||||||
"@types/express": "^4.17.13"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"honeybadger-checkins-sync": "scripts/check-ins-sync-bin.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@hookform/resolvers": {
|
"node_modules/@hookform/resolvers": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.2.tgz",
|
||||||
@@ -10984,20 +10956,6 @@
|
|||||||
"@types/estree": "*"
|
"@types/estree": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/aws-lambda": {
|
|
||||||
"version": "8.10.146",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.146.tgz",
|
|
||||||
"integrity": "sha512-3BaDXYTh0e6UCJYL/jwV/3+GRslSc08toAiZSmleYtkAUyV5rtvdPYxrG/88uqvTuT6sb27WE9OS90ZNTIuQ0g=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/body-parser": {
|
|
||||||
"version": "1.19.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
|
||||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/connect": "*",
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/cacheable-request": {
|
"node_modules/@types/cacheable-request": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||||
@@ -11010,14 +10968,6 @@
|
|||||||
"@types/responselike": "^1.0.0"
|
"@types/responselike": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/connect": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/cookie": {
|
"node_modules/@types/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||||
@@ -11140,28 +11090,6 @@
|
|||||||
"@types/estree": "*"
|
"@types/estree": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/express": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/body-parser": "*",
|
|
||||||
"@types/express-serve-static-core": "^4.17.33",
|
|
||||||
"@types/qs": "*",
|
|
||||||
"@types/serve-static": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/express-serve-static-core": {
|
|
||||||
"version": "4.19.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
|
||||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/qs": "*",
|
|
||||||
"@types/range-parser": "*",
|
|
||||||
"@types/send": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/formidable": {
|
"node_modules/@types/formidable": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz",
|
||||||
@@ -11204,11 +11132,6 @@
|
|||||||
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
|
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/http-errors": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||||
@@ -11278,11 +11201,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz",
|
||||||
"integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg=="
|
"integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/mime": {
|
|
||||||
"version": "1.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
|
||||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/minimatch": {
|
"node_modules/@types/minimatch": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
|
||||||
@@ -11420,11 +11338,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
||||||
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
|
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/qs": {
|
|
||||||
"version": "6.9.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz",
|
|
||||||
"integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/ramda": {
|
"node_modules/@types/ramda": {
|
||||||
"version": "0.29.9",
|
"version": "0.29.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.9.tgz",
|
||||||
@@ -11433,11 +11346,6 @@
|
|||||||
"types-ramda": "^0.29.6"
|
"types-ramda": "^0.29.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/range-parser": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
|
||||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.18",
|
"version": "18.2.18",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.18.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.18.tgz",
|
||||||
@@ -11493,25 +11401,6 @@
|
|||||||
"integrity": "sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==",
|
"integrity": "sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/send": {
|
|
||||||
"version": "0.17.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
|
||||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/mime": "^1",
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/serve-static": {
|
|
||||||
"version": "1.15.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
|
|
||||||
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/http-errors": "*",
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/send": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/swagger-ui-react": {
|
"node_modules/@types/swagger-ui-react": {
|
||||||
"version": "4.18.3",
|
"version": "4.18.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz",
|
||||||
@@ -21122,11 +21011,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||||
},
|
},
|
||||||
"node_modules/json-nd": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-nd/-/json-nd-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-8TIp0HZAY0VVrwRQJJPb4+nOTSPoOWZeEKBTLizUfQO4oym5Fc/MKqN8vEbLCxcyxDf2vwNxOQ1q84O49GWPyQ=="
|
|
||||||
},
|
|
||||||
"node_modules/json-parse-even-better-errors": {
|
"node_modules/json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
@@ -31365,25 +31249,6 @@
|
|||||||
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
|
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/stacktrace-parser": {
|
|
||||||
"version": "0.1.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
|
|
||||||
"integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
|
|
||||||
"dependencies": {
|
|
||||||
"type-fest": "^0.7.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/stacktrace-parser/node_modules/type-fest": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
|
|
||||||
"integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/stampit": {
|
"node_modules/stampit": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz",
|
||||||
@@ -36619,7 +36484,6 @@
|
|||||||
"@documenso/email": "*",
|
"@documenso/email": "*",
|
||||||
"@documenso/prisma": "*",
|
"@documenso/prisma": "*",
|
||||||
"@documenso/signing": "*",
|
"@documenso/signing": "*",
|
||||||
"@honeybadger-io/js": "^6.10.1",
|
|
||||||
"@lingui/core": "^4.11.3",
|
"@lingui/core": "^4.11.3",
|
||||||
"@lingui/macro": "^4.11.3",
|
"@lingui/macro": "^4.11.3",
|
||||||
"@lingui/react": "^4.11.3",
|
"@lingui/react": "^4.11.3",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.8.1-rc.3",
|
"version": "1.8.1-rc.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "turbo run build",
|
"build": "turbo run build",
|
||||||
"build:web": "turbo run build --filter=@documenso/web",
|
"build:web": "turbo run build --filter=@documenso/web",
|
||||||
|
|||||||
@@ -303,8 +303,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
|||||||
signingOrder: body.meta.signingOrder,
|
signingOrder: body.meta.signingOrder,
|
||||||
language: body.meta.language,
|
language: body.meta.language,
|
||||||
typedSignatureEnabled: body.meta.typedSignatureEnabled,
|
typedSignatureEnabled: body.meta.typedSignatureEnabled,
|
||||||
distributionMethod: body.meta.distributionMethod,
|
|
||||||
emailSettings: body.meta.emailSettings,
|
|
||||||
requestMetadata: extractNextApiRequestMetadata(args.req),
|
requestMetadata: extractNextApiRequestMetadata(args.req),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
ZDocumentActionAuthTypesSchema,
|
ZDocumentActionAuthTypesSchema,
|
||||||
ZRecipientActionAuthTypesSchema,
|
ZRecipientActionAuthTypesSchema,
|
||||||
} from '@documenso/lib/types/document-auth';
|
} from '@documenso/lib/types/document-auth';
|
||||||
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 {
|
import {
|
||||||
DocumentDataType,
|
DocumentDataType,
|
||||||
@@ -134,12 +133,8 @@ export const ZCreateDocumentMutationSchema = z.object({
|
|||||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||||
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
|
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
|
||||||
typedSignatureEnabled: z.boolean().optional().default(true),
|
typedSignatureEnabled: z.boolean().optional().default(true),
|
||||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod).optional(),
|
|
||||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
|
||||||
})
|
})
|
||||||
.partial()
|
.partial(),
|
||||||
.optional()
|
|
||||||
.default({}),
|
|
||||||
authOptions: z
|
authOptions: z
|
||||||
.object({
|
.object({
|
||||||
globalAccessAuth: ZDocumentAccessAuthTypesSchema.optional(),
|
globalAccessAuth: ZDocumentAccessAuthTypesSchema.optional(),
|
||||||
@@ -262,7 +257,6 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
|
|||||||
language: z.enum(SUPPORTED_LANGUAGE_CODES),
|
language: z.enum(SUPPORTED_LANGUAGE_CODES),
|
||||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
||||||
typedSignatureEnabled: z.boolean(),
|
typedSignatureEnabled: z.boolean(),
|
||||||
emailSettings: ZDocumentEmailSettingsSchema,
|
|
||||||
})
|
})
|
||||||
.partial()
|
.partial()
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ export const getTeamPrices = async () => {
|
|||||||
const priceIds = prices.map((price) => price.id);
|
const priceIds = prices.map((price) => price.id);
|
||||||
|
|
||||||
if (!monthlyPrice || !yearlyPrice) {
|
if (!monthlyPrice || !yearlyPrice) {
|
||||||
throw new AppError('INVALID_CONFIG', {
|
throw new AppError('INVALID_CONFIG', 'Missing monthly or yearly price');
|
||||||
message: 'Missing monthly or yearly price',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ export const transferTeamSubscription = async ({
|
|||||||
const teamCustomerId = team.customerId;
|
const teamCustomerId = team.customerId;
|
||||||
|
|
||||||
if (!teamCustomerId) {
|
if (!teamCustomerId) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Missing customer ID.');
|
||||||
message: 'Missing customer ID.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const [teamRelatedPlanPriceIds, teamSeatPrices] = await Promise.all([
|
const [teamRelatedPlanPriceIds, teamSeatPrices] = await Promise.all([
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export const TemplateDocumentInvite = ({
|
|||||||
<>
|
<>
|
||||||
{includeSenderDetails ? (
|
{includeSenderDetails ? (
|
||||||
<Trans>
|
<Trans>
|
||||||
{inviterName} on behalf of "{teamName}" has invited you to{' '}
|
{inviterName} on behalf of {teamName} has invited you to{' '}
|
||||||
{_(actionVerb).toLowerCase()}
|
{_(actionVerb).toLowerCase()}
|
||||||
</Trans>
|
</Trans>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const DocumentInviteEmailTemplate = ({
|
|||||||
|
|
||||||
if (isTeamInvite) {
|
if (isTeamInvite) {
|
||||||
previewText = includeSenderDetails
|
previewText = includeSenderDetails
|
||||||
? msg`${inviterName} on behalf of "${teamName}" has invited you to ${action} ${documentName}`
|
? msg`${inviterName} on behalf of ${teamName} has invited you to ${action} ${documentName}`
|
||||||
: msg`${teamName} has invited you to ${action} ${documentName}`;
|
: msg`${teamName} has invited you to ${action} ${documentName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,6 @@ export const DocumentInviteEmailTemplate = ({
|
|||||||
|
|
||||||
<Container className="mx-auto mt-12 max-w-xl">
|
<Container className="mx-auto mt-12 max-w-xl">
|
||||||
<Section>
|
<Section>
|
||||||
{!isTeamInvite && (
|
|
||||||
<Text className="my-4 text-base font-semibold">
|
<Text className="my-4 text-base font-semibold">
|
||||||
<Trans>
|
<Trans>
|
||||||
{inviterName}{' '}
|
{inviterName}{' '}
|
||||||
@@ -99,7 +98,6 @@ export const DocumentInviteEmailTemplate = ({
|
|||||||
</Link>
|
</Link>
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
|
||||||
|
|
||||||
<Text className="mt-2 text-base text-slate-400">
|
<Text className="mt-2 text-base text-slate-400">
|
||||||
{customBody ? (
|
{customBody ? (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { TRPCError } from '@trpc/server';
|
import { TRPCError } from '@trpc/server';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@@ -8,69 +8,46 @@ import { TRPCClientError } from '@documenso/trpc/client';
|
|||||||
* Generic application error codes.
|
* Generic application error codes.
|
||||||
*/
|
*/
|
||||||
export enum AppErrorCode {
|
export enum AppErrorCode {
|
||||||
'ALREADY_EXISTS' = 'ALREADY_EXISTS',
|
'ALREADY_EXISTS' = 'AlreadyExists',
|
||||||
'EXPIRED_CODE' = 'EXPIRED_CODE',
|
'EXPIRED_CODE' = 'ExpiredCode',
|
||||||
'INVALID_BODY' = 'INVALID_BODY',
|
'INVALID_BODY' = 'InvalidBody',
|
||||||
'INVALID_REQUEST' = 'INVALID_REQUEST',
|
'INVALID_REQUEST' = 'InvalidRequest',
|
||||||
'LIMIT_EXCEEDED' = 'LIMIT_EXCEEDED',
|
'LIMIT_EXCEEDED' = 'LimitExceeded',
|
||||||
'NOT_FOUND' = 'NOT_FOUND',
|
'NOT_FOUND' = 'NotFound',
|
||||||
'NOT_SETUP' = 'NOT_SETUP',
|
'NOT_SETUP' = 'NotSetup',
|
||||||
'UNAUTHORIZED' = 'UNAUTHORIZED',
|
'UNAUTHORIZED' = 'Unauthorized',
|
||||||
'UNKNOWN_ERROR' = 'UNKNOWN_ERROR',
|
'UNKNOWN_ERROR' = 'UnknownError',
|
||||||
'RETRY_EXCEPTION' = 'RETRY_EXCEPTION',
|
'RETRY_EXCEPTION' = 'RetryException',
|
||||||
'SCHEMA_FAILED' = 'SCHEMA_FAILED',
|
'SCHEMA_FAILED' = 'SchemaFailed',
|
||||||
'TOO_MANY_REQUESTS' = 'TOO_MANY_REQUESTS',
|
'TOO_MANY_REQUESTS' = 'TooManyRequests',
|
||||||
'PROFILE_URL_TAKEN' = 'PROFILE_URL_TAKEN',
|
'PROFILE_URL_TAKEN' = 'ProfileUrlTaken',
|
||||||
'PREMIUM_PROFILE_URL' = 'PREMIUM_PROFILE_URL',
|
'PREMIUM_PROFILE_URL' = 'PremiumProfileUrl',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const genericErrorCodeToTrpcErrorCodeMap: Record<
|
const genericErrorCodeToTrpcErrorCodeMap: Record<string, TRPCError['code']> = {
|
||||||
string,
|
[AppErrorCode.ALREADY_EXISTS]: 'BAD_REQUEST',
|
||||||
{ code: TRPCError['code']; status: number }
|
[AppErrorCode.EXPIRED_CODE]: 'BAD_REQUEST',
|
||||||
> = {
|
[AppErrorCode.INVALID_BODY]: 'BAD_REQUEST',
|
||||||
[AppErrorCode.ALREADY_EXISTS]: { code: 'BAD_REQUEST', status: 400 },
|
[AppErrorCode.INVALID_REQUEST]: 'BAD_REQUEST',
|
||||||
[AppErrorCode.EXPIRED_CODE]: { code: 'BAD_REQUEST', status: 400 },
|
[AppErrorCode.NOT_FOUND]: 'NOT_FOUND',
|
||||||
[AppErrorCode.INVALID_BODY]: { code: 'BAD_REQUEST', status: 400 },
|
[AppErrorCode.NOT_SETUP]: 'BAD_REQUEST',
|
||||||
[AppErrorCode.INVALID_REQUEST]: { code: 'BAD_REQUEST', status: 400 },
|
[AppErrorCode.UNAUTHORIZED]: 'UNAUTHORIZED',
|
||||||
[AppErrorCode.NOT_FOUND]: { code: 'NOT_FOUND', status: 404 },
|
[AppErrorCode.UNKNOWN_ERROR]: 'INTERNAL_SERVER_ERROR',
|
||||||
[AppErrorCode.NOT_SETUP]: { code: 'BAD_REQUEST', status: 400 },
|
[AppErrorCode.RETRY_EXCEPTION]: 'INTERNAL_SERVER_ERROR',
|
||||||
[AppErrorCode.UNAUTHORIZED]: { code: 'UNAUTHORIZED', status: 401 },
|
[AppErrorCode.SCHEMA_FAILED]: 'INTERNAL_SERVER_ERROR',
|
||||||
[AppErrorCode.UNKNOWN_ERROR]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
[AppErrorCode.TOO_MANY_REQUESTS]: 'TOO_MANY_REQUESTS',
|
||||||
[AppErrorCode.RETRY_EXCEPTION]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
[AppErrorCode.PROFILE_URL_TAKEN]: 'BAD_REQUEST',
|
||||||
[AppErrorCode.SCHEMA_FAILED]: { code: 'INTERNAL_SERVER_ERROR', status: 500 },
|
[AppErrorCode.PREMIUM_PROFILE_URL]: 'BAD_REQUEST',
|
||||||
[AppErrorCode.TOO_MANY_REQUESTS]: { code: 'TOO_MANY_REQUESTS', status: 429 },
|
|
||||||
[AppErrorCode.PROFILE_URL_TAKEN]: { code: 'BAD_REQUEST', status: 400 },
|
|
||||||
[AppErrorCode.PREMIUM_PROFILE_URL]: { code: 'BAD_REQUEST', status: 400 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZAppErrorJsonSchema = z.object({
|
export const ZAppErrorJsonSchema = z.object({
|
||||||
code: z.string(),
|
code: z.string(),
|
||||||
message: z.string().optional(),
|
message: z.string().optional(),
|
||||||
userMessage: z.string().optional(),
|
userMessage: z.string().optional(),
|
||||||
statusCode: z.number().optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TAppErrorJsonSchema = z.infer<typeof ZAppErrorJsonSchema>;
|
export type TAppErrorJsonSchema = z.infer<typeof ZAppErrorJsonSchema>;
|
||||||
|
|
||||||
type AppErrorOptions = {
|
|
||||||
/**
|
|
||||||
* An internal message for logging.
|
|
||||||
*/
|
|
||||||
message?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A message which can be potientially displayed to the user.
|
|
||||||
*/
|
|
||||||
userMessage?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The status code to be associated with the error.
|
|
||||||
*
|
|
||||||
* Mainly used for API -> Frontend communication and logging filtering.
|
|
||||||
*/
|
|
||||||
statusCode?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class AppError extends Error {
|
export class AppError extends Error {
|
||||||
/**
|
/**
|
||||||
* The error code.
|
* The error code.
|
||||||
@@ -82,11 +59,6 @@ export class AppError extends Error {
|
|||||||
*/
|
*/
|
||||||
userMessage?: string;
|
userMessage?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* The status code to be associated with the error.
|
|
||||||
*/
|
|
||||||
statusCode?: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AppError.
|
* Create a new AppError.
|
||||||
*
|
*
|
||||||
@@ -94,12 +66,10 @@ export class AppError extends Error {
|
|||||||
* @param message An internal error message.
|
* @param message An internal error message.
|
||||||
* @param userMessage A error message which can be displayed to the user.
|
* @param userMessage A error message which can be displayed to the user.
|
||||||
*/
|
*/
|
||||||
public constructor(errorCode: string, options?: AppErrorOptions) {
|
public constructor(errorCode: string, message?: string, userMessage?: string) {
|
||||||
super(options?.message || errorCode);
|
super(message || errorCode);
|
||||||
|
|
||||||
this.code = errorCode;
|
this.code = errorCode;
|
||||||
this.userMessage = options?.userMessage;
|
this.userMessage = userMessage;
|
||||||
this.statusCode = options?.statusCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,21 +84,16 @@ export class AppError extends Error {
|
|||||||
|
|
||||||
// Handle TRPC errors.
|
// Handle TRPC errors.
|
||||||
if (error instanceof TRPCClientError) {
|
if (error instanceof TRPCClientError) {
|
||||||
const parsedJsonError = AppError.parseFromJSON(error.data?.appError);
|
const parsedJsonError = AppError.parseFromJSONString(error.message);
|
||||||
|
return parsedJsonError || new AppError('UnknownError', error.message);
|
||||||
const fallbackError = new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
|
||||||
message: error.message,
|
|
||||||
});
|
|
||||||
|
|
||||||
return parsedJsonError || fallbackError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle completely unknown errors.
|
// Handle completely unknown errors.
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
const { code, message, userMessage, statusCode } = error as {
|
const { code, message, userMessage } = error as {
|
||||||
code: unknown;
|
code: unknown;
|
||||||
message: unknown;
|
message: unknown;
|
||||||
statusCode: unknown;
|
status: unknown;
|
||||||
userMessage: unknown;
|
userMessage: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,15 +102,16 @@ export class AppError extends Error {
|
|||||||
const validUserMessage: string | undefined =
|
const validUserMessage: string | undefined =
|
||||||
typeof userMessage === 'string' ? userMessage : undefined;
|
typeof userMessage === 'string' ? userMessage : undefined;
|
||||||
|
|
||||||
const validStatusCode = typeof statusCode === 'number' ? statusCode : undefined;
|
return new AppError(validCode, validMessage, validUserMessage);
|
||||||
|
}
|
||||||
|
|
||||||
const options: AppErrorOptions = {
|
static parseErrorToTRPCError(error: unknown): TRPCError {
|
||||||
message: validMessage,
|
const appError = AppError.parseError(error);
|
||||||
userMessage: validUserMessage,
|
|
||||||
statusCode: validStatusCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
return new AppError(validCode, options);
|
return new TRPCError({
|
||||||
|
code: genericErrorCodeToTrpcErrorCodeMap[appError.code] || 'BAD_REQUEST',
|
||||||
|
message: AppError.toJSONString(appError),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,26 +120,12 @@ export class AppError extends Error {
|
|||||||
* @param appError The AppError to convert to JSON.
|
* @param appError The AppError to convert to JSON.
|
||||||
* @returns A JSON object representing the AppError.
|
* @returns A JSON object representing the AppError.
|
||||||
*/
|
*/
|
||||||
static toJSON({ code, message, userMessage, statusCode }: AppError): TAppErrorJsonSchema {
|
static toJSON({ code, message, userMessage }: AppError): TAppErrorJsonSchema {
|
||||||
const data: TAppErrorJsonSchema = {
|
return {
|
||||||
code,
|
code,
|
||||||
|
message,
|
||||||
|
userMessage,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Explicity only set values if it exists, since TRPC will add meta for undefined
|
|
||||||
// values which clutters up API responses.
|
|
||||||
if (message) {
|
|
||||||
data.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userMessage) {
|
|
||||||
data.userMessage = userMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusCode) {
|
|
||||||
data.statusCode = statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,21 +138,15 @@ export class AppError extends Error {
|
|||||||
return JSON.stringify(AppError.toJSON(appError));
|
return JSON.stringify(AppError.toJSON(appError));
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseFromJSON(value: unknown): AppError | null {
|
static parseFromJSONString(jsonString: string): AppError | null {
|
||||||
try {
|
try {
|
||||||
const parsed = ZAppErrorJsonSchema.safeParse(value);
|
const parsed = ZAppErrorJsonSchema.safeParse(JSON.parse(jsonString));
|
||||||
|
|
||||||
if (!parsed.success) {
|
if (!parsed.success) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { message, userMessage, statusCode } = parsed.data;
|
return new AppError(parsed.data.code, parsed.data.message, parsed.data.userMessage);
|
||||||
|
|
||||||
return new AppError(parsed.data.code, {
|
|
||||||
message,
|
|
||||||
userMessage,
|
|
||||||
statusCode,
|
|
||||||
});
|
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
|||||||
if (!emailMessage) {
|
if (!emailMessage) {
|
||||||
emailMessage = i18n._(
|
emailMessage = i18n._(
|
||||||
team.teamGlobalSettings?.includeSenderDetails
|
team.teamGlobalSettings?.includeSenderDetails
|
||||||
? msg`${user.name} on behalf of "${team.name}" has invited you to ${recipientActionVerb} the document "${document.title}".`
|
? msg`${user.name} on behalf of ${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`
|
||||||
: msg`${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`,
|
: msg`${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export const SEAL_DOCUMENT_JOB_DEFINITION = {
|
|||||||
|
|
||||||
const pdfData = await getFile(documentData);
|
const pdfData = await getFile(documentData);
|
||||||
const certificateData =
|
const certificateData =
|
||||||
document.team?.teamGlobalSettings?.includeSigningCertificate ?? true
|
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
|
||||||
? await getCertificatePdf({
|
? await getCertificatePdf({
|
||||||
documentId,
|
documentId,
|
||||||
language: document.documentMeta?.language,
|
language: document.documentMeta?.language,
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
"@documenso/email": "*",
|
"@documenso/email": "*",
|
||||||
"@documenso/prisma": "*",
|
"@documenso/prisma": "*",
|
||||||
"@documenso/signing": "*",
|
"@documenso/signing": "*",
|
||||||
"@honeybadger-io/js": "^6.10.1",
|
|
||||||
"@lingui/core": "^4.11.3",
|
"@lingui/core": "^4.11.3",
|
||||||
"@lingui/macro": "^4.11.3",
|
"@lingui/macro": "^4.11.3",
|
||||||
"@lingui/react": "^4.11.3",
|
"@lingui/react": "^4.11.3",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const getDocumentStats = async () => {
|
|||||||
[ExtendedDocumentStatus.DRAFT]: 0,
|
[ExtendedDocumentStatus.DRAFT]: 0,
|
||||||
[ExtendedDocumentStatus.PENDING]: 0,
|
[ExtendedDocumentStatus.PENDING]: 0,
|
||||||
[ExtendedDocumentStatus.COMPLETED]: 0,
|
[ExtendedDocumentStatus.COMPLETED]: 0,
|
||||||
|
[ExtendedDocumentStatus.BIN]: 0,
|
||||||
[ExtendedDocumentStatus.ALL]: 0,
|
[ExtendedDocumentStatus.ALL]: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,7 @@ export const createPasskeyAuthenticationOptions = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!preferredPasskey) {
|
if (!preferredPasskey) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Requested passkey not found');
|
||||||
message: 'Requested passkey not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ export const createPasskey = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!verificationToken) {
|
if (!verificationToken) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Challenge token not found');
|
||||||
message: 'Challenge token not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.verificationToken.deleteMany({
|
await prisma.verificationToken.deleteMany({
|
||||||
@@ -63,9 +61,7 @@ export const createPasskey = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (verificationToken.expires < new Date()) {
|
if (verificationToken.expires < new Date()) {
|
||||||
throw new AppError(AppErrorCode.EXPIRED_CODE, {
|
throw new AppError(AppErrorCode.EXPIRED_CODE, 'Challenge token expired');
|
||||||
message: 'Challenge token expired',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rpId: expectedRPID, origin: expectedOrigin } = getAuthenticatorOptions();
|
const { rpId: expectedRPID, origin: expectedOrigin } = getAuthenticatorOptions();
|
||||||
@@ -78,9 +74,7 @@ export const createPasskey = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!verification.verified || !verification.registrationInfo) {
|
if (!verification.verified || !verification.registrationInfo) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Verification failed');
|
||||||
message: 'Verification failed',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { credentialPublicKey, credentialID, counter, credentialDeviceType, credentialBackedUp } =
|
const { credentialPublicKey, credentialID, counter, credentialDeviceType, credentialBackedUp } =
|
||||||
|
|||||||
@@ -47,9 +47,7 @@ export const createDocument = async ({
|
|||||||
teamId !== undefined &&
|
teamId !== undefined &&
|
||||||
!user.teamMembers.some((teamMember) => teamMember.teamId === teamId)
|
!user.teamMembers.some((teamMember) => teamMember.teamId === teamId)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
||||||
message: 'Team not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let team: (Team & { teamGlobalSettings: TeamGlobalSettings | null }) | null = null;
|
let team: (Team & { teamGlobalSettings: TeamGlobalSettings | null }) | null = null;
|
||||||
|
|||||||
@@ -158,6 +158,16 @@ const handleDocumentOwnerDelete = async ({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Soft delete for document recipients since the owner is deleting it
|
||||||
|
await tx.recipient.updateMany({
|
||||||
|
where: {
|
||||||
|
documentId: document.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
documentDeletedAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await tx.document.update({
|
return await tx.document.update({
|
||||||
where: {
|
where: {
|
||||||
id: document.id,
|
id: document.id,
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export const findDocumentAuditLogs = async ({
|
|||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
|
||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED,
|
||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
||||||
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED,
|
||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED,
|
||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED,
|
||||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED,
|
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED,
|
||||||
|
|||||||
@@ -2,15 +2,8 @@ import { DateTime } from 'luxon';
|
|||||||
import { P, match } from 'ts-pattern';
|
import { P, match } from 'ts-pattern';
|
||||||
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
|
import type { Document, DocumentSource, Team, TeamEmail, User } from '@documenso/prisma/client';
|
||||||
import type {
|
import { Prisma, RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
|
||||||
Document,
|
|
||||||
DocumentSource,
|
|
||||||
Prisma,
|
|
||||||
Team,
|
|
||||||
TeamEmail,
|
|
||||||
User,
|
|
||||||
} from '@documenso/prisma/client';
|
|
||||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||||
|
|
||||||
import { DocumentVisibility } from '../../types/document-visibility';
|
import { DocumentVisibility } from '../../types/document-visibility';
|
||||||
@@ -88,14 +81,12 @@ export const findDocuments = async ({
|
|||||||
const teamMemberRole = team?.members[0].role ?? null;
|
const teamMemberRole = team?.members[0].role ?? null;
|
||||||
|
|
||||||
const termFilters = match(term)
|
const termFilters = match(term)
|
||||||
.with(P.string.minLength(1), () => {
|
.with(P.string.minLength(1), () => ({
|
||||||
return {
|
|
||||||
title: {
|
title: {
|
||||||
contains: term,
|
contains: term,
|
||||||
mode: 'insensitive',
|
mode: Prisma.QueryMode.insensitive,
|
||||||
},
|
},
|
||||||
} as const;
|
}))
|
||||||
})
|
|
||||||
.otherwise(() => undefined);
|
.otherwise(() => undefined);
|
||||||
|
|
||||||
const searchFilter: Prisma.DocumentWhereInput = {
|
const searchFilter: Prisma.DocumentWhereInput = {
|
||||||
@@ -141,6 +132,8 @@ export const findDocuments = async ({
|
|||||||
|
|
||||||
let filters: Prisma.DocumentWhereInput | null = findDocumentsFilter(status, user);
|
let filters: Prisma.DocumentWhereInput | null = findDocumentsFilter(status, user);
|
||||||
|
|
||||||
|
console.log('find documets team', team);
|
||||||
|
|
||||||
if (team) {
|
if (team) {
|
||||||
filters = findTeamDocumentsFilter(status, team, visibilityFilters);
|
filters = findTeamDocumentsFilter(status, team, visibilityFilters);
|
||||||
}
|
}
|
||||||
@@ -293,19 +286,21 @@ export const findDocuments = async ({
|
|||||||
} satisfies FindResultSet<typeof data>;
|
} satisfies FindResultSet<typeof data>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
||||||
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput>(status)
|
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput>(status)
|
||||||
.with(ExtendedDocumentStatus.ALL, () => ({
|
.with(ExtendedDocumentStatus.ALL, () => ({
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: null,
|
teamId: null,
|
||||||
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -314,6 +309,7 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -330,6 +326,7 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
role: {
|
role: {
|
||||||
not: RecipientRole.CC,
|
not: RecipientRole.CC,
|
||||||
},
|
},
|
||||||
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
@@ -344,6 +341,7 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: null,
|
teamId: null,
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
@@ -354,6 +352,7 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
role: {
|
role: {
|
||||||
not: RecipientRole.CC,
|
not: RecipientRole.CC,
|
||||||
},
|
},
|
||||||
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -365,12 +364,49 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: null,
|
teamId: null,
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
.with(ExtendedDocumentStatus.BIN, () => ({
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
userId: user.id,
|
||||||
|
teamId: null,
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: user.email,
|
||||||
|
signingStatus: SigningStatus.SIGNED,
|
||||||
|
documentDeletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: user.email,
|
||||||
|
signingStatus: SigningStatus.SIGNED,
|
||||||
|
documentDeletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -408,7 +444,7 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
|||||||
* @param team The team to find the documents for.
|
* @param team The team to find the documents for.
|
||||||
* @returns A filter which can be applied to the Prisma Document schema.
|
* @returns A filter which can be applied to the Prisma Document schema.
|
||||||
*/
|
*/
|
||||||
const findTeamDocumentsFilter = (
|
export const findTeamDocumentsFilter = (
|
||||||
status: ExtendedDocumentStatus,
|
status: ExtendedDocumentStatus,
|
||||||
team: Team & { teamEmail: TeamEmail | null },
|
team: Team & { teamEmail: TeamEmail | null },
|
||||||
visibilityFilters: Prisma.DocumentWhereInput[],
|
visibilityFilters: Prisma.DocumentWhereInput[],
|
||||||
@@ -418,17 +454,16 @@ const findTeamDocumentsFilter = (
|
|||||||
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput | null>(status)
|
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput | null>(status)
|
||||||
.with(ExtendedDocumentStatus.ALL, () => {
|
.with(ExtendedDocumentStatus.ALL, () => {
|
||||||
const filter: Prisma.DocumentWhereInput = {
|
const filter: Prisma.DocumentWhereInput = {
|
||||||
// Filter to display all documents that belong to the team.
|
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
teamId: team.id,
|
teamId: team.id,
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (teamEmail && filter.OR) {
|
if (teamEmail && filter.OR) {
|
||||||
// Filter to display all documents received by the team email that are not draft.
|
|
||||||
filter.OR.push({
|
filter.OR.push({
|
||||||
status: {
|
status: {
|
||||||
not: ExtendedDocumentStatus.DRAFT,
|
not: ExtendedDocumentStatus.DRAFT,
|
||||||
@@ -438,14 +473,15 @@ const findTeamDocumentsFilter = (
|
|||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter to display all documents that have been sent by the team email.
|
|
||||||
filter.OR.push({
|
filter.OR.push({
|
||||||
User: {
|
User: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
},
|
},
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -453,7 +489,6 @@ const findTeamDocumentsFilter = (
|
|||||||
return filter;
|
return filter;
|
||||||
})
|
})
|
||||||
.with(ExtendedDocumentStatus.INBOX, () => {
|
.with(ExtendedDocumentStatus.INBOX, () => {
|
||||||
// Return a filter that will return nothing.
|
|
||||||
if (!teamEmail) {
|
if (!teamEmail) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -471,6 +506,7 @@ const findTeamDocumentsFilter = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -480,6 +516,7 @@ const findTeamDocumentsFilter = (
|
|||||||
{
|
{
|
||||||
teamId: team.id,
|
teamId: team.id,
|
||||||
status: ExtendedDocumentStatus.DRAFT,
|
status: ExtendedDocumentStatus.DRAFT,
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -491,6 +528,7 @@ const findTeamDocumentsFilter = (
|
|||||||
User: {
|
User: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
},
|
},
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -503,6 +541,7 @@ const findTeamDocumentsFilter = (
|
|||||||
{
|
{
|
||||||
teamId: team.id,
|
teamId: team.id,
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
deletedAt: null,
|
||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -531,6 +570,7 @@ const findTeamDocumentsFilter = (
|
|||||||
OR: visibilityFilters,
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
deletedAt: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,6 +579,7 @@ const findTeamDocumentsFilter = (
|
|||||||
.with(ExtendedDocumentStatus.COMPLETED, () => {
|
.with(ExtendedDocumentStatus.COMPLETED, () => {
|
||||||
const filter: Prisma.DocumentWhereInput = {
|
const filter: Prisma.DocumentWhereInput = {
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
deletedAt: null,
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
teamId: team.id,
|
teamId: team.id,
|
||||||
@@ -568,5 +609,42 @@ const findTeamDocumentsFilter = (
|
|||||||
|
|
||||||
return filter;
|
return filter;
|
||||||
})
|
})
|
||||||
|
.with(ExtendedDocumentStatus.BIN, () => {
|
||||||
|
const filters: Prisma.DocumentWhereInput[] = [
|
||||||
|
{
|
||||||
|
teamId: team.id,
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (teamEmail) {
|
||||||
|
filters.push(
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
email: teamEmail,
|
||||||
|
},
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: teamEmail,
|
||||||
|
documentDeletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
OR: filters,
|
||||||
|
};
|
||||||
|
})
|
||||||
.exhaustive();
|
.exhaustive();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { prisma } from '@documenso/prisma';
|
|||||||
import type { Prisma } from '@documenso/prisma/client';
|
import type { Prisma } from '@documenso/prisma/client';
|
||||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
|
||||||
import { DocumentVisibility } from '../../types/document-visibility';
|
import { DocumentVisibility } from '../../types/document-visibility';
|
||||||
import { getTeamById } from '../team/get-team';
|
import { getTeamById } from '../team/get-team';
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ export const getDocumentById = async ({ id, userId, teamId }: GetDocumentByIdOpt
|
|||||||
teamId,
|
teamId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const document = await prisma.document.findFirst({
|
return await prisma.document.findFirstOrThrow({
|
||||||
where: documentWhereInput,
|
where: documentWhereInput,
|
||||||
include: {
|
include: {
|
||||||
documentData: true,
|
documentData: true,
|
||||||
@@ -46,14 +45,6 @@ export const getDocumentById = async ({ id, userId, teamId }: GetDocumentByIdOpt
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!document) {
|
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
|
||||||
message: 'Document could not be found',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return document;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GetDocumentWhereInputOptions = {
|
export type GetDocumentWhereInputOptions = {
|
||||||
|
|||||||
@@ -81,17 +81,6 @@ export const getDocumentAndSenderByToken = async ({
|
|||||||
token,
|
token,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
team: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
teamEmail: true,
|
|
||||||
teamGlobalSettings: {
|
|
||||||
select: {
|
|
||||||
includeSenderDetails: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -118,9 +107,7 @@ export const getDocumentAndSenderByToken = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!documentAccessValid) {
|
if (!documentAccessValid) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid access values');
|
||||||
message: 'Invalid access values',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -180,9 +167,7 @@ export const getDocumentAndRecipientByToken = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!documentAccessValid) {
|
if (!documentAccessValid) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid access values');
|
||||||
message: 'Invalid access values',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
118
packages/lib/server-only/document/get-stats-new.tsx
Normal file
118
packages/lib/server-only/document/get-stats-new.tsx
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import { DateTime } from 'luxon';
|
||||||
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
|
import {
|
||||||
|
type PeriodSelectorValue,
|
||||||
|
findDocumentsFilter,
|
||||||
|
findTeamDocumentsFilter,
|
||||||
|
} from '@documenso/lib/server-only/document/find-documents';
|
||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
import type { Prisma, Team, TeamEmail, User } from '@documenso/prisma/client';
|
||||||
|
import { DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client';
|
||||||
|
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||||
|
|
||||||
|
export type GetStatsInput = {
|
||||||
|
user: User;
|
||||||
|
team?: Team & { teamEmail: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
|
||||||
|
period?: PeriodSelectorValue;
|
||||||
|
search?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getStats = async ({ user, period, search, ...options }: GetStatsInput) => {
|
||||||
|
let createdAt: Prisma.DocumentWhereInput['createdAt'];
|
||||||
|
|
||||||
|
if (period) {
|
||||||
|
const daysAgo = parseInt(period.replace(/d$/, ''), 10);
|
||||||
|
|
||||||
|
const startOfPeriod = DateTime.now().minus({ days: daysAgo }).startOf('day');
|
||||||
|
|
||||||
|
createdAt = {
|
||||||
|
gte: startOfPeriod.toJSDate(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const stats: Record<ExtendedDocumentStatus, number> = {
|
||||||
|
[ExtendedDocumentStatus.DRAFT]: 0,
|
||||||
|
[ExtendedDocumentStatus.PENDING]: 0,
|
||||||
|
[ExtendedDocumentStatus.COMPLETED]: 0,
|
||||||
|
[ExtendedDocumentStatus.INBOX]: 0,
|
||||||
|
[ExtendedDocumentStatus.ALL]: 0,
|
||||||
|
[ExtendedDocumentStatus.BIN]: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchFilter: Prisma.DocumentWhereInput = search
|
||||||
|
? {
|
||||||
|
OR: [
|
||||||
|
{ title: { contains: search, mode: 'insensitive' } },
|
||||||
|
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
|
||||||
|
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
|
||||||
|
const visibilityFilters = [
|
||||||
|
match(options.team?.currentTeamMember?.role)
|
||||||
|
.with(TeamMemberRole.ADMIN, () => ({
|
||||||
|
visibility: {
|
||||||
|
in: [
|
||||||
|
DocumentVisibility.EVERYONE,
|
||||||
|
DocumentVisibility.MANAGER_AND_ABOVE,
|
||||||
|
DocumentVisibility.ADMIN,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
.with(TeamMemberRole.MANAGER, () => ({
|
||||||
|
visibility: {
|
||||||
|
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
.otherwise(() => ({ visibility: DocumentVisibility.EVERYONE })),
|
||||||
|
];
|
||||||
|
|
||||||
|
const statusCounts = await Promise.all(
|
||||||
|
Object.values(ExtendedDocumentStatus).map(async (status) => {
|
||||||
|
if (status === ExtendedDocumentStatus.ALL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filter = options.team
|
||||||
|
? findTeamDocumentsFilter(status, options.team, visibilityFilters)
|
||||||
|
: findDocumentsFilter(status, user);
|
||||||
|
|
||||||
|
if (filter === null) {
|
||||||
|
return { status, count: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const whereClause = {
|
||||||
|
...filter,
|
||||||
|
...(createdAt && { createdAt }),
|
||||||
|
...searchFilter,
|
||||||
|
};
|
||||||
|
|
||||||
|
const count = await prisma.document.count({
|
||||||
|
where: whereClause,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { status, count };
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
statusCounts.forEach((result) => {
|
||||||
|
if (result) {
|
||||||
|
stats[result.status] = result.count;
|
||||||
|
if (
|
||||||
|
result.status !== ExtendedDocumentStatus.BIN &&
|
||||||
|
[
|
||||||
|
ExtendedDocumentStatus.DRAFT,
|
||||||
|
ExtendedDocumentStatus.PENDING,
|
||||||
|
ExtendedDocumentStatus.COMPLETED,
|
||||||
|
ExtendedDocumentStatus.INBOX,
|
||||||
|
].includes(result.status)
|
||||||
|
) {
|
||||||
|
stats[ExtendedDocumentStatus.ALL] += result.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
};
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
|
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
|
||||||
import type { Prisma, User } from '@documenso/prisma/client';
|
import type { Prisma, User } from '@documenso/prisma/client';
|
||||||
import { SigningStatus } from '@documenso/prisma/client';
|
import {
|
||||||
import { DocumentVisibility } from '@documenso/prisma/client';
|
DocumentVisibility,
|
||||||
|
RecipientRole,
|
||||||
|
SigningStatus,
|
||||||
|
TeamMemberRole,
|
||||||
|
} from '@documenso/prisma/client';
|
||||||
import { isExtendedDocumentStatus } from '@documenso/prisma/guards/is-extended-document-status';
|
import { isExtendedDocumentStatus } from '@documenso/prisma/guards/is-extended-document-status';
|
||||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||||
|
|
||||||
@@ -30,7 +34,7 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const [ownerCounts, notSignedCounts, hasSignedCounts] = await (options.team
|
const [ownerCounts, notSignedCounts, hasSignedCounts, deletedCounts] = await (options.team
|
||||||
? getTeamCounts({
|
? getTeamCounts({
|
||||||
...options.team,
|
...options.team,
|
||||||
createdAt,
|
createdAt,
|
||||||
@@ -46,6 +50,7 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
|
|||||||
[ExtendedDocumentStatus.COMPLETED]: 0,
|
[ExtendedDocumentStatus.COMPLETED]: 0,
|
||||||
[ExtendedDocumentStatus.INBOX]: 0,
|
[ExtendedDocumentStatus.INBOX]: 0,
|
||||||
[ExtendedDocumentStatus.ALL]: 0,
|
[ExtendedDocumentStatus.ALL]: 0,
|
||||||
|
[ExtendedDocumentStatus.BIN]: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
ownerCounts.forEach((stat) => {
|
ownerCounts.forEach((stat) => {
|
||||||
@@ -66,6 +71,10 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
deletedCounts.forEach((stat) => {
|
||||||
|
stats[ExtendedDocumentStatus.BIN] += stat._count._all;
|
||||||
|
});
|
||||||
|
|
||||||
Object.keys(stats).forEach((key) => {
|
Object.keys(stats).forEach((key) => {
|
||||||
if (key !== ExtendedDocumentStatus.ALL && isExtendedDocumentStatus(key)) {
|
if (key !== ExtendedDocumentStatus.ALL && isExtendedDocumentStatus(key)) {
|
||||||
stats[ExtendedDocumentStatus.ALL] += stats[key];
|
stats[ExtendedDocumentStatus.ALL] += stats[key];
|
||||||
@@ -98,25 +107,45 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
|||||||
_all: true,
|
_all: true,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
createdAt,
|
|
||||||
teamId: null,
|
teamId: null,
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: {
|
||||||
|
not: ExtendedDocumentStatus.DRAFT,
|
||||||
|
},
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: user.email,
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
createdAt,
|
||||||
AND: [searchFilter],
|
AND: [searchFilter],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
// Not signed counts.
|
// Not signed counts (Inbox).
|
||||||
prisma.document.groupBy({
|
prisma.document.groupBy({
|
||||||
by: ['status'],
|
by: ['status'],
|
||||||
_count: {
|
_count: {
|
||||||
_all: true,
|
_all: true,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: {
|
||||||
|
not: ExtendedDocumentStatus.DRAFT,
|
||||||
|
},
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
signingStatus: SigningStatus.NOT_SIGNED,
|
signingStatus: SigningStatus.NOT_SIGNED,
|
||||||
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
documentDeletedAt: null,
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -131,30 +160,81 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
|||||||
_all: true,
|
_all: true,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
createdAt,
|
|
||||||
User: {
|
|
||||||
email: {
|
|
||||||
not: user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OR: [
|
OR: [
|
||||||
|
{
|
||||||
|
userId: user.id,
|
||||||
|
teamId: null,
|
||||||
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
signingStatus: SigningStatus.SIGNED,
|
signingStatus: SigningStatus.SIGNED,
|
||||||
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
documentDeletedAt: null,
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
userId: user.id,
|
||||||
|
teamId: null,
|
||||||
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: user.email,
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
createdAt,
|
||||||
|
AND: [searchFilter],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// Deleted counts.
|
||||||
|
prisma.document.groupBy({
|
||||||
|
by: ['status'],
|
||||||
|
_count: {
|
||||||
|
_all: true,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
userId: user.id,
|
||||||
|
teamId: null,
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: user.email,
|
||||||
|
signingStatus: SigningStatus.SIGNED,
|
||||||
|
documentDeletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
signingStatus: SigningStatus.SIGNED,
|
documentDeletedAt: {
|
||||||
documentDeletedAt: null,
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -177,9 +257,7 @@ type GetTeamCountsOption = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getTeamCounts = async (options: GetTeamCountsOption) => {
|
const getTeamCounts = async (options: GetTeamCountsOption) => {
|
||||||
const { createdAt, teamId, teamEmail } = options;
|
const { createdAt, teamId, teamEmail, senderIds = [], currentTeamMemberRole, search } = options;
|
||||||
|
|
||||||
const senderIds = options.senderIds ?? [];
|
|
||||||
|
|
||||||
const userIdWhereClause: Prisma.DocumentWhereInput['userId'] =
|
const userIdWhereClause: Prisma.DocumentWhereInput['userId'] =
|
||||||
senderIds.length > 0
|
senderIds.length > 0
|
||||||
@@ -188,30 +266,18 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
|
|||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const searchFilter: Prisma.DocumentWhereInput = {
|
const searchFilter: Prisma.DocumentWhereInput = search
|
||||||
|
? {
|
||||||
OR: [
|
OR: [
|
||||||
{ title: { contains: options.search, mode: 'insensitive' } },
|
{ title: { contains: search, mode: 'insensitive' } },
|
||||||
{ Recipient: { some: { name: { contains: options.search, mode: 'insensitive' } } } },
|
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
|
||||||
{ Recipient: { some: { email: { contains: options.search, mode: 'insensitive' } } } },
|
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
|
: {};
|
||||||
|
|
||||||
let ownerCountsWhereInput: Prisma.DocumentWhereInput = {
|
const visibilityFilters = [
|
||||||
userId: userIdWhereClause,
|
match(currentTeamMemberRole)
|
||||||
createdAt,
|
|
||||||
teamId,
|
|
||||||
deletedAt: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
let notSignedCountsGroupByArgs = null;
|
|
||||||
let hasSignedCountsGroupByArgs = null;
|
|
||||||
|
|
||||||
const visibilityFiltersWhereInput: Prisma.DocumentWhereInput = {
|
|
||||||
AND: [
|
|
||||||
{ deletedAt: null },
|
|
||||||
{
|
|
||||||
OR: [
|
|
||||||
match(options.currentTeamMemberRole)
|
|
||||||
.with(TeamMemberRole.ADMIN, () => ({
|
.with(TeamMemberRole.ADMIN, () => ({
|
||||||
visibility: {
|
visibility: {
|
||||||
in: [
|
in: [
|
||||||
@@ -226,110 +292,200 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
|
|||||||
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
|
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
.otherwise(() => ({
|
.otherwise(() => ({ visibility: DocumentVisibility.EVERYONE })),
|
||||||
visibility: {
|
];
|
||||||
equals: DocumentVisibility.EVERYONE,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
{
|
|
||||||
OR: [
|
|
||||||
{ userId: options.userId },
|
|
||||||
{ Recipient: { some: { email: options.currentUserEmail } } },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
ownerCountsWhereInput = {
|
return Promise.all([
|
||||||
...ownerCountsWhereInput,
|
// Owner counts (ALL)
|
||||||
...visibilityFiltersWhereInput,
|
prisma.document.groupBy({
|
||||||
...searchFilter,
|
by: ['status'],
|
||||||
};
|
_count: { _all: true },
|
||||||
|
where: {
|
||||||
if (teamEmail) {
|
|
||||||
ownerCountsWhereInput = {
|
|
||||||
userId: userIdWhereClause,
|
|
||||||
createdAt,
|
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
teamId,
|
teamId,
|
||||||
|
deletedAt: null,
|
||||||
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
...(teamEmail
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
status: {
|
||||||
|
not: ExtendedDocumentStatus.DRAFT,
|
||||||
|
},
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: teamEmail,
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deletedAt: null,
|
||||||
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
User: {
|
User: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
],
|
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
};
|
OR: visibilityFilters,
|
||||||
|
|
||||||
notSignedCountsGroupByArgs = {
|
|
||||||
by: ['status'],
|
|
||||||
_count: {
|
|
||||||
_all: true,
|
|
||||||
},
|
},
|
||||||
where: {
|
]
|
||||||
|
: []),
|
||||||
|
],
|
||||||
userId: userIdWhereClause,
|
userId: userIdWhereClause,
|
||||||
createdAt,
|
createdAt,
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
...searchFilter,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Not signed counts (INBOX)
|
||||||
|
prisma.document.groupBy({
|
||||||
|
by: ['status'],
|
||||||
|
_count: { _all: true },
|
||||||
|
where: teamEmail
|
||||||
|
? {
|
||||||
|
userId: userIdWhereClause,
|
||||||
|
createdAt,
|
||||||
|
status: {
|
||||||
|
not: ExtendedDocumentStatus.DRAFT,
|
||||||
|
},
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
signingStatus: SigningStatus.NOT_SIGNED,
|
signingStatus: SigningStatus.NOT_SIGNED,
|
||||||
documentDeletedAt: null,
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
|
OR: visibilityFilters,
|
||||||
|
...searchFilter,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
userId: userIdWhereClause,
|
||||||
|
createdAt,
|
||||||
|
AND: [
|
||||||
|
{
|
||||||
|
OR: [{ id: -1 }], // Empty set if no team email
|
||||||
},
|
},
|
||||||
} satisfies Prisma.DocumentGroupByArgs;
|
searchFilter,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
hasSignedCountsGroupByArgs = {
|
// Has signed counts (PENDING + COMPLETED)
|
||||||
|
prisma.document.groupBy({
|
||||||
by: ['status'],
|
by: ['status'],
|
||||||
_count: {
|
_count: { _all: true },
|
||||||
_all: true,
|
|
||||||
},
|
|
||||||
where: {
|
where: {
|
||||||
userId: userIdWhereClause,
|
userId: userIdWhereClause,
|
||||||
createdAt,
|
createdAt,
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
|
teamId,
|
||||||
status: ExtendedDocumentStatus.PENDING,
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
deletedAt: null,
|
||||||
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
teamId,
|
||||||
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
deletedAt: null,
|
||||||
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
...(teamEmail
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
status: ExtendedDocumentStatus.PENDING,
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
signingStatus: SigningStatus.SIGNED,
|
signingStatus: SigningStatus.SIGNED,
|
||||||
|
role: {
|
||||||
|
not: RecipientRole.CC,
|
||||||
|
},
|
||||||
documentDeletedAt: null,
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
email: teamEmail,
|
||||||
|
},
|
||||||
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
],
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: ExtendedDocumentStatus.COMPLETED,
|
status: ExtendedDocumentStatus.COMPLETED,
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
Recipient: {
|
Recipient: {
|
||||||
some: {
|
some: {
|
||||||
email: teamEmail,
|
email: teamEmail,
|
||||||
signingStatus: SigningStatus.SIGNED,
|
|
||||||
documentDeletedAt: null,
|
documentDeletedAt: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
deletedAt: null,
|
OR: visibilityFilters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
email: teamEmail,
|
||||||
|
},
|
||||||
|
OR: visibilityFilters,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
deletedAt: null,
|
||||||
},
|
},
|
||||||
} satisfies Prisma.DocumentGroupByArgs;
|
]
|
||||||
}
|
: []),
|
||||||
|
],
|
||||||
|
...searchFilter,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
return Promise.all([
|
// Deleted counts (BIN)
|
||||||
prisma.document.groupBy({
|
prisma.document.groupBy({
|
||||||
by: ['status'],
|
by: ['status'],
|
||||||
_count: {
|
_count: { _all: true },
|
||||||
_all: true,
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
teamId,
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...(teamEmail
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
email: teamEmail,
|
||||||
|
},
|
||||||
|
deletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Recipient: {
|
||||||
|
some: {
|
||||||
|
email: teamEmail,
|
||||||
|
documentDeletedAt: {
|
||||||
|
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
],
|
||||||
|
...searchFilter,
|
||||||
},
|
},
|
||||||
where: ownerCountsWhereInput,
|
|
||||||
}),
|
}),
|
||||||
notSignedCountsGroupByArgs ? prisma.document.groupBy(notSignedCountsGroupByArgs) : [],
|
|
||||||
hasSignedCountsGroupByArgs ? prisma.document.groupBy(hasSignedCountsGroupByArgs) : [],
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,9 +106,7 @@ export const isRecipientAuthorized = async ({
|
|||||||
|
|
||||||
// Should not be possible.
|
// Should not be possible.
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||||
message: 'User not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await verifyTwoFactorAuthenticationToken({
|
return await verifyTwoFactorAuthenticationToken({
|
||||||
@@ -166,9 +164,7 @@ const verifyPasskey = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!passkey) {
|
if (!passkey) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Passkey not found');
|
||||||
message: 'Passkey not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const verificationToken = await prisma.verificationToken
|
const verificationToken = await prisma.verificationToken
|
||||||
@@ -181,15 +177,11 @@ const verifyPasskey = async ({
|
|||||||
.catch(() => null);
|
.catch(() => null);
|
||||||
|
|
||||||
if (!verificationToken) {
|
if (!verificationToken) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Token not found');
|
||||||
message: 'Token not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verificationToken.expires < new Date()) {
|
if (verificationToken.expires < new Date()) {
|
||||||
throw new AppError(AppErrorCode.EXPIRED_CODE, {
|
throw new AppError(AppErrorCode.EXPIRED_CODE, 'Token expired');
|
||||||
message: 'Token expired',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rpId, origin } = getAuthenticatorOptions();
|
const { rpId, origin } = getAuthenticatorOptions();
|
||||||
@@ -207,9 +199,7 @@ const verifyPasskey = async ({
|
|||||||
}).catch(() => null); // May want to log this for insights.
|
}).catch(() => null); // May want to log this for insights.
|
||||||
|
|
||||||
if (verification?.verified !== true) {
|
if (verification?.verified !== true) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'User is not authorized');
|
||||||
message: 'User is not authorized',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.passkey.update({
|
await prisma.passkey.update({
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export const resendDocument = async ({
|
|||||||
emailMessage =
|
emailMessage =
|
||||||
customEmail?.message ||
|
customEmail?.message ||
|
||||||
i18n._(
|
i18n._(
|
||||||
msg`${user.name} on behalf of "${document.team.name}" has invited you to ${recipientActionVerb} the document "${document.title}".`,
|
msg`${user.name} on behalf of ${document.team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
149
packages/lib/server-only/document/restore-document.ts
Normal file
149
packages/lib/server-only/document/restore-document.ts
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
'use server';
|
||||||
|
|
||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
import type { Document, DocumentMeta, Recipient, User } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
|
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||||
|
|
||||||
|
export type RestoreDocumentOptions = {
|
||||||
|
id: number;
|
||||||
|
userId: number;
|
||||||
|
teamId?: number;
|
||||||
|
requestMetadata?: RequestMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const restoreDocument = async ({
|
||||||
|
id,
|
||||||
|
userId,
|
||||||
|
teamId,
|
||||||
|
requestMetadata,
|
||||||
|
}: RestoreDocumentOptions) => {
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new Error('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = await prisma.document.findUnique({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
Recipient: true,
|
||||||
|
documentMeta: true,
|
||||||
|
team: {
|
||||||
|
select: {
|
||||||
|
members: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!document || (teamId !== undefined && teamId !== document.teamId)) {
|
||||||
|
throw new Error('Document not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const isUserOwner = document.userId === userId;
|
||||||
|
const isUserTeamMember = document.team?.members.some((member) => member.userId === userId);
|
||||||
|
const userRecipient = document.Recipient.find((recipient) => recipient.email === user.email);
|
||||||
|
|
||||||
|
if (!isUserOwner && !isUserTeamMember && !userRecipient) {
|
||||||
|
throw new Error('Not allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle restoring the actual document if user has permission.
|
||||||
|
if (isUserOwner || isUserTeamMember) {
|
||||||
|
await handleDocumentOwnerRestore({
|
||||||
|
document,
|
||||||
|
user,
|
||||||
|
requestMetadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue to show the document to the user if they are a recipient.
|
||||||
|
if (userRecipient?.documentDeletedAt !== null) {
|
||||||
|
await prisma.recipient
|
||||||
|
.update({
|
||||||
|
where: {
|
||||||
|
id: userRecipient?.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// Do nothing.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return partial document for API v1 response.
|
||||||
|
return {
|
||||||
|
id: document.id,
|
||||||
|
userId: document.userId,
|
||||||
|
teamId: document.teamId,
|
||||||
|
title: document.title,
|
||||||
|
status: document.status,
|
||||||
|
documentDataId: document.documentDataId,
|
||||||
|
createdAt: document.createdAt,
|
||||||
|
updatedAt: document.updatedAt,
|
||||||
|
completedAt: document.completedAt,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type HandleDocumentOwnerRestoreOptions = {
|
||||||
|
document: Document & {
|
||||||
|
Recipient: Recipient[];
|
||||||
|
documentMeta: DocumentMeta | null;
|
||||||
|
};
|
||||||
|
user: User;
|
||||||
|
requestMetadata?: RequestMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDocumentOwnerRestore = async ({
|
||||||
|
document,
|
||||||
|
user,
|
||||||
|
requestMetadata,
|
||||||
|
}: HandleDocumentOwnerRestoreOptions) => {
|
||||||
|
if (!document.deletedAt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore soft-deleted documents.
|
||||||
|
return await prisma.$transaction(async (tx) => {
|
||||||
|
await tx.documentAuditLog.create({
|
||||||
|
data: createDocumentAuditLogData({
|
||||||
|
documentId: document.id,
|
||||||
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED,
|
||||||
|
user,
|
||||||
|
requestMetadata,
|
||||||
|
data: {
|
||||||
|
type: 'RESTORE',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.recipient.updateMany({
|
||||||
|
where: {
|
||||||
|
documentId: document.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
documentDeletedAt: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return await tx.document.update({
|
||||||
|
where: {
|
||||||
|
id: document.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -101,7 +101,7 @@ export const sealDocument = async ({
|
|||||||
const pdfData = await getFile(documentData);
|
const pdfData = await getFile(documentData);
|
||||||
|
|
||||||
const certificateData =
|
const certificateData =
|
||||||
document.team?.teamGlobalSettings?.includeSigningCertificate ?? true
|
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
|
||||||
? await getCertificatePdf({
|
? await getCertificatePdf({
|
||||||
documentId,
|
documentId,
|
||||||
language: document.documentMeta?.language,
|
language: document.documentMeta?.language,
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ export const updateDocumentSettings = async ({
|
|||||||
requestMetadata,
|
requestMetadata,
|
||||||
}: UpdateDocumentSettingsOptions) => {
|
}: UpdateDocumentSettingsOptions) => {
|
||||||
if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) {
|
if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||||
message: 'Missing data to update',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findFirstOrThrow({
|
const user = await prisma.user.findFirstOrThrow({
|
||||||
@@ -98,9 +96,10 @@ export const updateDocumentSettings = async ({
|
|||||||
!allowedVisibilities.includes(document.visibility) ||
|
!allowedVisibilities.includes(document.visibility) ||
|
||||||
(data.visibility && !allowedVisibilities.includes(data.visibility))
|
(data.visibility && !allowedVisibilities.includes(data.visibility))
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to update the document visibility',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to update the document visibility',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with(TeamMemberRole.MEMBER, () => {
|
.with(TeamMemberRole.MEMBER, () => {
|
||||||
@@ -108,15 +107,17 @@ export const updateDocumentSettings = async ({
|
|||||||
document.visibility !== DocumentVisibility.EVERYONE ||
|
document.visibility !== DocumentVisibility.EVERYONE ||
|
||||||
(data.visibility && data.visibility !== DocumentVisibility.EVERYONE)
|
(data.visibility && data.visibility !== DocumentVisibility.EVERYONE)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to update the document visibility',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to update the document visibility',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.otherwise(() => {
|
.otherwise(() => {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to update the document',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to update the document',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,9 +142,10 @@ export const updateDocumentSettings = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isDocumentEnterprise) {
|
if (!isDocumentEnterprise) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to set the action auth',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to set the action auth',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +161,10 @@ export const updateDocumentSettings = async ({
|
|||||||
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
||||||
|
|
||||||
if (!isTitleSame && document.status !== DocumentStatus.DRAFT) {
|
if (!isTitleSame && document.status !== DocumentStatus.DRAFT) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(
|
||||||
message: 'You cannot update the title if the document has been sent',
|
AppErrorCode.INVALID_BODY,
|
||||||
});
|
'You cannot update the title if the document has been sent',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTitleSame) {
|
if (!isTitleSame) {
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ export const validateFieldAuth = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||||
message: 'Invalid authentication values',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return derivedRecipientActionAuth;
|
return derivedRecipientActionAuth;
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import { getToken } from 'next-auth/jwt';
|
|||||||
import { LOCAL_FEATURE_FLAGS } from '@documenso/lib/constants/feature-flags';
|
import { LOCAL_FEATURE_FLAGS } from '@documenso/lib/constants/feature-flags';
|
||||||
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app';
|
import {
|
||||||
|
NEXT_PRIVATE_INTERNAL_WEBAPP_URL,
|
||||||
|
NEXT_PUBLIC_MARKETING_URL,
|
||||||
|
NEXT_PUBLIC_WEBAPP_URL,
|
||||||
|
} from '../../constants/app';
|
||||||
import { extractDistinctUserId, mapJwtToFlagProperties } from './get';
|
import { extractDistinctUserId, mapJwtToFlagProperties } from './get';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ import { getToken } from 'next-auth/jwt';
|
|||||||
import { LOCAL_FEATURE_FLAGS, extractPostHogConfig } from '@documenso/lib/constants/feature-flags';
|
import { LOCAL_FEATURE_FLAGS, extractPostHogConfig } from '@documenso/lib/constants/feature-flags';
|
||||||
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app';
|
import {
|
||||||
|
NEXT_PRIVATE_INTERNAL_WEBAPP_URL,
|
||||||
|
NEXT_PUBLIC_MARKETING_URL,
|
||||||
|
NEXT_PUBLIC_WEBAPP_URL,
|
||||||
|
} from '../../constants/app';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate a single feature flag based on the current user if possible.
|
* Evaluate a single feature flag based on the current user if possible.
|
||||||
|
|||||||
@@ -104,9 +104,7 @@ export const setFieldsForDocument = async ({
|
|||||||
|
|
||||||
// Each field MUST have a recipient associated with it.
|
// Each field MUST have a recipient associated with it.
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(AppErrorCode.INVALID_REQUEST, `Recipient not found for field ${field.id}`);
|
||||||
message: `Recipient not found for field ${field.id}`,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the existing field can be modified.
|
// Check whether the existing field can be modified.
|
||||||
@@ -115,10 +113,10 @@ export const setFieldsForDocument = async ({
|
|||||||
hasFieldBeenChanged(existing, field) &&
|
hasFieldBeenChanged(existing, field) &&
|
||||||
!canRecipientFieldsBeModified(recipient, existingFields)
|
!canRecipientFieldsBeModified(recipient, existingFields)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(
|
||||||
message:
|
AppErrorCode.INVALID_REQUEST,
|
||||||
'Cannot modify a field where the recipient has already interacted with the document',
|
'Cannot modify a field where the recipient has already interacted with the document',
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -115,9 +115,7 @@ export const getPublicProfileByUrl = async ({
|
|||||||
// Log as critical error.
|
// Log as critical error.
|
||||||
if (user?.profile && team?.profile) {
|
if (user?.profile && team?.profile) {
|
||||||
console.error('Profile URL is ambiguous', { profileUrl, userId: user.id, teamId: team.id });
|
console.error('Profile URL is ambiguous', { profileUrl, userId: user.id, teamId: team.id });
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Profile URL is ambiguous');
|
||||||
message: 'Profile URL is ambiguous',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user?.profile?.enabled) {
|
if (user?.profile?.enabled) {
|
||||||
@@ -179,7 +177,5 @@ export const getPublicProfileByUrl = async ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Profile not found');
|
||||||
message: 'Profile not found',
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ export const getTeamTokens = async ({ userId, teamId }: GetUserTokensOptions) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (teamMember?.role !== TeamMemberRole.ADMIN) {
|
if (teamMember?.role !== TeamMemberRole.ADMIN) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have the required permissions to view this page.',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have the required permissions to view this page.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await prisma.apiToken.findMany({
|
return await prisma.apiToken.findMany({
|
||||||
|
|||||||
@@ -105,9 +105,10 @@ export const setRecipientsForDocument = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isDocumentEnterprise) {
|
if (!isDocumentEnterprise) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to set the action auth',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to set the action auth',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,9 +142,10 @@ export const setRecipientsForDocument = async ({
|
|||||||
hasRecipientBeenChanged(existing, recipient) &&
|
hasRecipientBeenChanged(existing, recipient) &&
|
||||||
!canRecipientBeModified(existing, document.Field)
|
!canRecipientBeModified(existing, document.Field)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(
|
||||||
message: 'Cannot modify a recipient who has already interacted with the document',
|
AppErrorCode.INVALID_REQUEST,
|
||||||
});
|
'Cannot modify a recipient who has already interacted with the document',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -72,9 +72,10 @@ export const setRecipientsForTemplate = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isDocumentEnterprise) {
|
if (!isDocumentEnterprise) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to set the action auth',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to set the action auth',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,15 +119,14 @@ export const setRecipientsForTemplate = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (updatedDirectRecipient?.role === RecipientRole.CC) {
|
if (updatedDirectRecipient?.role === RecipientRole.CC) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Cannot set direct recipient as CC');
|
||||||
message: 'Cannot set direct recipient as CC',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deletedDirectRecipient) {
|
if (deletedDirectRecipient) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(
|
||||||
message: 'Cannot delete direct recipient while direct template exists',
|
AppErrorCode.INVALID_BODY,
|
||||||
});
|
'Cannot delete direct recipient while direct template exists',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,9 +96,10 @@ export const updateRecipient = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isDocumentEnterprise) {
|
if (!isDocumentEnterprise) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to set the action auth',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to set the action auth',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ export const createTeamPendingCheckoutSession = async ({
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
// Absorb all the errors incase Stripe throws something sensitive.
|
// Absorb all the errors incase Stripe throws something sensitive.
|
||||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
throw new AppError(AppErrorCode.UNKNOWN_ERROR, 'Something went wrong.');
|
||||||
message: 'Something went wrong.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ export const createTeamEmailVerification = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (team.teamEmail || team.emailVerification) {
|
if (team.teamEmail || team.emailVerification) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(
|
||||||
message: 'Team already has an email or existing email verification.',
|
AppErrorCode.INVALID_REQUEST,
|
||||||
});
|
'Team already has an email or existing email verification.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingTeamEmail = await tx.teamEmail.findFirst({
|
const existingTeamEmail = await tx.teamEmail.findFirst({
|
||||||
@@ -67,9 +68,7 @@ export const createTeamEmailVerification = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (existingTeamEmail) {
|
if (existingTeamEmail) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Email already taken by another team.');
|
||||||
message: 'Email already taken by another team.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
||||||
@@ -98,9 +97,7 @@ export const createTeamEmailVerification = async ({
|
|||||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||||
|
|
||||||
if (err.code === 'P2002' && target.success && target.data.includes('email')) {
|
if (err.code === 'P2002' && target.success && target.data.includes('email')) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Email already taken by another team.');
|
||||||
message: 'Email already taken by another team.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -69,9 +69,7 @@ export const createTeamMemberInvites = async ({
|
|||||||
const currentTeamMember = team.members.find((member) => member.user.id === userId);
|
const currentTeamMember = team.members.find((member) => member.user.id === userId);
|
||||||
|
|
||||||
if (!currentTeamMember) {
|
if (!currentTeamMember) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'User not part of team.');
|
||||||
message: 'User not part of team.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const usersToInvite = invitations.filter((invitation) => {
|
const usersToInvite = invitations.filter((invitation) => {
|
||||||
@@ -93,9 +91,10 @@ export const createTeamMemberInvites = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (unauthorizedRoleAccess) {
|
if (unauthorizedRoleAccess) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'User does not have permission to set high level roles',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'User does not have permission to set high level roles',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const teamMemberInvites = usersToInvite.map(({ email, role }) => ({
|
const teamMemberInvites = usersToInvite.map(({ email, role }) => ({
|
||||||
@@ -128,10 +127,11 @@ export const createTeamMemberInvites = async ({
|
|||||||
if (sendEmailResultErrorList.length > 0) {
|
if (sendEmailResultErrorList.length > 0) {
|
||||||
console.error(JSON.stringify(sendEmailResultErrorList));
|
console.error(JSON.stringify(sendEmailResultErrorList));
|
||||||
|
|
||||||
throw new AppError('EmailDeliveryFailed', {
|
throw new AppError(
|
||||||
message: 'Failed to send invite emails to one or more users.',
|
'EmailDeliveryFailed',
|
||||||
userMessage: `Failed to send invites to ${sendEmailResultErrorList.length}/${teamMemberInvites.length} users.`,
|
'Failed to send invite emails to one or more users.',
|
||||||
});
|
`Failed to send invites to ${sendEmailResultErrorList.length}/${teamMemberInvites.length} users.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -87,9 +87,7 @@ export const createTeam = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (existingUserProfileWithUrl) {
|
if (existingUserProfileWithUrl) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'URL already taken.');
|
||||||
message: 'URL already taken.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await tx.team.create({
|
await tx.team.create({
|
||||||
@@ -133,21 +131,15 @@ export const createTeam = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (existingUserProfileWithUrl) {
|
if (existingUserProfileWithUrl) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'URL already taken.');
|
||||||
message: 'URL already taken.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingTeamWithUrl) {
|
if (existingTeamWithUrl) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||||
message: 'Team URL already exists.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!customerId) {
|
if (!customerId) {
|
||||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
throw new AppError(AppErrorCode.UNKNOWN_ERROR, 'Missing customer ID for pending teams.');
|
||||||
message: 'Missing customer ID for pending teams.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await tx.teamPending.create({
|
return await tx.teamPending.create({
|
||||||
@@ -174,9 +166,7 @@ export const createTeam = async ({
|
|||||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||||
|
|
||||||
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||||
message: 'Team URL already exists.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -60,13 +60,11 @@ export const deleteTeamMembers = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!currentTeamMember) {
|
if (!currentTeamMember) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team member record does not exist');
|
||||||
message: 'Team member record does not exist',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (teamMembersToRemove.find((member) => member.userId === team.ownerUserId)) {
|
if (teamMembersToRemove.find((member) => member.userId === team.ownerUserId)) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'Cannot remove the team owner' });
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot remove the team owner');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMemberToRemoveHigherRole = teamMembersToRemove.some(
|
const isMemberToRemoveHigherRole = teamMembersToRemove.some(
|
||||||
@@ -74,9 +72,7 @@ export const deleteTeamMembers = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isMemberToRemoveHigherRole) {
|
if (isMemberToRemoveHigherRole) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot remove a member with a higher role');
|
||||||
message: 'Cannot remove a member with a higher role',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the team members.
|
// Remove the team members.
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ export const findTeamInvoices = async ({ userId, teamId }: FindTeamInvoicesOptio
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!team.customerId) {
|
if (!team.customerId) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team has no customer ID.');
|
||||||
message: 'Team has no customer ID.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const results = await getInvoices({ customerId: team.customerId });
|
const results = await getInvoices({ customerId: team.customerId });
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ export const getTeamPublicProfile = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!team) {
|
if (!team) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
||||||
message: 'Team not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and return the public profile.
|
// Create and return the public profile.
|
||||||
@@ -49,9 +47,7 @@ export const getTeamPublicProfile = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Failed to create public profile');
|
||||||
message: 'Failed to create public profile',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -38,17 +38,16 @@ export const resendTeamEmailVerification = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!team) {
|
if (!team) {
|
||||||
throw new AppError('TeamNotFound', {
|
throw new AppError('TeamNotFound', 'User is not a member of the team.');
|
||||||
message: 'User is not a member of the team.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { emailVerification } = team;
|
const { emailVerification } = team;
|
||||||
|
|
||||||
if (!emailVerification) {
|
if (!emailVerification) {
|
||||||
throw new AppError('VerificationNotFound', {
|
throw new AppError(
|
||||||
message: 'No team email verification exists for this team.',
|
'VerificationNotFound',
|
||||||
});
|
'No team email verification exists for this team.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
const { token, expiresAt } = createTokenVerification({ hours: 1 });
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const resendTeamMemberInvitation = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!team) {
|
if (!team) {
|
||||||
throw new AppError('TeamNotFound', { message: 'User is not a valid member of the team.' });
|
throw new AppError('TeamNotFound', 'User is not a valid member of the team.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const teamMemberInvite = await tx.teamMemberInvite.findUniqueOrThrow({
|
const teamMemberInvite = await tx.teamMemberInvite.findUniqueOrThrow({
|
||||||
@@ -66,7 +66,7 @@ export const resendTeamMemberInvitation = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!teamMemberInvite) {
|
if (!teamMemberInvite) {
|
||||||
throw new AppError('InviteNotFound', { message: 'No invite exists for this user.' });
|
throw new AppError('InviteNotFound', 'No invite exists for this user.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendTeamMemberInviteEmail({
|
await sendTeamMemberInviteEmail({
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ export const updateTeamMember = async ({
|
|||||||
const teamMemberToUpdate = team.members.find((member) => member.id === teamMemberId);
|
const teamMemberToUpdate = team.members.find((member) => member.id === teamMemberId);
|
||||||
|
|
||||||
if (!teamMemberToUpdate || !currentTeamMember) {
|
if (!teamMemberToUpdate || !currentTeamMember) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Team member does not exist' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team member does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (teamMemberToUpdate.userId === team.ownerUserId) {
|
if (teamMemberToUpdate.userId === team.ownerUserId) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'Cannot update the owner' });
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot update the owner');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMemberToUpdateHigherRole = !isTeamRoleWithinUserHierarchy(
|
const isMemberToUpdateHigherRole = !isTeamRoleWithinUserHierarchy(
|
||||||
@@ -61,9 +61,7 @@ export const updateTeamMember = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isMemberToUpdateHigherRole) {
|
if (isMemberToUpdateHigherRole) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Cannot update a member with a higher role');
|
||||||
message: 'Cannot update a member with a higher role',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isNewMemberRoleHigherThanCurrentRole = !isTeamRoleWithinUserHierarchy(
|
const isNewMemberRoleHigherThanCurrentRole = !isTeamRoleWithinUserHierarchy(
|
||||||
@@ -72,9 +70,10 @@ export const updateTeamMember = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isNewMemberRoleHigherThanCurrentRole) {
|
if (isNewMemberRoleHigherThanCurrentRole) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'Cannot give a member a role higher than the user initating the update',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'Cannot give a member a role higher than the user initating the update',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await tx.teamMember.update({
|
return await tx.teamMember.update({
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ export const updateTeam = async ({ userId, teamId, data }: UpdateTeamOptions) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (foundPendingTeamWithUrl) {
|
if (foundPendingTeamWithUrl) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||||
message: 'Team URL already exists.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const team = await tx.team.update({
|
const team = await tx.team.update({
|
||||||
@@ -59,9 +57,7 @@ export const updateTeam = async ({ userId, teamId, data }: UpdateTeamOptions) =>
|
|||||||
const target = z.array(z.string()).safeParse(err.meta?.target);
|
const target = z.array(z.string()).safeParse(err.meta?.target);
|
||||||
|
|
||||||
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
if (err.code === 'P2002' && target.success && target.data.includes('url')) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, {
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Team URL already exists.');
|
||||||
message: 'Team URL already exists.',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export const createDocumentFromDirectTemplate = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template?.directLink?.enabled) {
|
if (!template?.directLink?.enabled) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, { message: 'Invalid or missing template' });
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Invalid or missing template');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Recipient: recipients, directLink, User: templateOwner } = template;
|
const { Recipient: recipients, directLink, User: templateOwner } = template;
|
||||||
@@ -111,19 +111,15 @@ export const createDocumentFromDirectTemplate = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!directTemplateRecipient || directTemplateRecipient.role === RecipientRole.CC) {
|
if (!directTemplateRecipient || directTemplateRecipient.role === RecipientRole.CC) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Invalid or missing direct recipient');
|
||||||
message: 'Invalid or missing direct recipient',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.updatedAt.getTime() !== templateUpdatedAt.getTime()) {
|
if (template.updatedAt.getTime() !== templateUpdatedAt.getTime()) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, { message: 'Template no longer matches' });
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Template no longer matches');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user && user.email !== directRecipientEmail) {
|
if (user && user.email !== directRecipientEmail) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Email must match if you are logged in');
|
||||||
message: 'Email must match if you are logged in',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { derivedRecipientAccessAuth, documentAuthOption: templateAuthOptions } =
|
const { derivedRecipientAccessAuth, documentAuthOption: templateAuthOptions } =
|
||||||
@@ -140,7 +136,7 @@ export const createDocumentFromDirectTemplate = async ({
|
|||||||
.exhaustive();
|
.exhaustive();
|
||||||
|
|
||||||
if (!isAccessAuthValid) {
|
if (!isAccessAuthValid) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, { message: 'You must be logged in' });
|
throw new AppError(AppErrorCode.UNAUTHORIZED, 'You must be logged in');
|
||||||
}
|
}
|
||||||
|
|
||||||
const directTemplateRecipientAuthOptions = ZRecipientAuthOptionsSchema.parse(
|
const directTemplateRecipientAuthOptions = ZRecipientAuthOptionsSchema.parse(
|
||||||
@@ -167,9 +163,7 @@ export const createDocumentFromDirectTemplate = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!signedFieldValue) {
|
if (!signedFieldValue) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Invalid, missing or changed fields');
|
||||||
message: 'Invalid, missing or changed fields',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateField.type === FieldType.NAME && directRecipientName === undefined) {
|
if (templateField.type === FieldType.NAME && directRecipientName === undefined) {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import type { SupportedLanguageCodes } from '../../constants/i18n';
|
|||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import { ZRecipientAuthOptionsSchema } from '../../types/document-auth';
|
import { ZRecipientAuthOptionsSchema } from '../../types/document-auth';
|
||||||
import type { TDocumentEmailSettings } from '../../types/document-email';
|
|
||||||
import { ZFieldMetaSchema } from '../../types/field-meta';
|
import { ZFieldMetaSchema } from '../../types/field-meta';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||||
@@ -66,7 +65,6 @@ export type CreateDocumentFromTemplateOptions = {
|
|||||||
language?: SupportedLanguageCodes;
|
language?: SupportedLanguageCodes;
|
||||||
distributionMethod?: DocumentDistributionMethod;
|
distributionMethod?: DocumentDistributionMethod;
|
||||||
typedSignatureEnabled?: boolean;
|
typedSignatureEnabled?: boolean;
|
||||||
emailSettings?: TDocumentEmailSettings;
|
|
||||||
};
|
};
|
||||||
requestMetadata?: RequestMetadata;
|
requestMetadata?: RequestMetadata;
|
||||||
};
|
};
|
||||||
@@ -122,9 +120,7 @@ export const createDocumentFromTemplate = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||||
message: 'Template not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all the passed in recipient IDs can be associated with a template recipient.
|
// Check that all the passed in recipient IDs can be associated with a template recipient.
|
||||||
@@ -134,9 +130,10 @@ export const createDocumentFromTemplate = async ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!foundRecipient) {
|
if (!foundRecipient) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(
|
||||||
message: `Recipient with ID ${recipient.id} not found in the template.`,
|
AppErrorCode.INVALID_BODY,
|
||||||
});
|
`Recipient with ID ${recipient.id} not found in the template.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -191,9 +188,7 @@ export const createDocumentFromTemplate = async ({
|
|||||||
redirectUrl: override?.redirectUrl || template.templateMeta?.redirectUrl,
|
redirectUrl: override?.redirectUrl || template.templateMeta?.redirectUrl,
|
||||||
distributionMethod:
|
distributionMethod:
|
||||||
override?.distributionMethod || template.templateMeta?.distributionMethod,
|
override?.distributionMethod || template.templateMeta?.distributionMethod,
|
||||||
// last `undefined` is due to JsonValue's
|
emailSettings: template.templateMeta?.emailSettings || undefined,
|
||||||
emailSettings:
|
|
||||||
override?.emailSettings || template.templateMeta?.emailSettings || undefined,
|
|
||||||
signingOrder:
|
signingOrder:
|
||||||
override?.signingOrder ||
|
override?.signingOrder ||
|
||||||
template.templateMeta?.signingOrder ||
|
template.templateMeta?.signingOrder ||
|
||||||
|
|||||||
@@ -47,18 +47,18 @@ export const createTemplateDirectLink = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Template not found' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.directLink) {
|
if (template.directLink) {
|
||||||
throw new AppError(AppErrorCode.ALREADY_EXISTS, { message: 'Direct template already exists' });
|
throw new AppError(AppErrorCode.ALREADY_EXISTS, 'Direct template already exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
directRecipientId &&
|
directRecipientId &&
|
||||||
!template.Recipient.find((recipient) => recipient.id === directRecipientId)
|
!template.Recipient.find((recipient) => recipient.id === directRecipientId)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Recipient not found' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Recipient not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -67,9 +67,7 @@ export const createTemplateDirectLink = async ({
|
|||||||
(recipient) => recipient.email.toLowerCase() === DIRECT_TEMPLATE_RECIPIENT_EMAIL,
|
(recipient) => recipient.email.toLowerCase() === DIRECT_TEMPLATE_RECIPIENT_EMAIL,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Cannot generate placeholder direct recipient');
|
||||||
message: 'Cannot generate placeholder direct recipient',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
return await prisma.$transaction(async (tx) => {
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ export const deleteTemplateDirectLink = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||||
message: 'Template not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { directLink } = template;
|
const { directLink } = template;
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ export const getTemplateById = async ({ id, userId, teamId }: GetTemplateByIdOpt
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||||
message: 'Template not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import type { TemplateWithDetails } from '@documenso/prisma/types/template';
|
import type { TemplateWithDetails } from '@documenso/prisma/types/template';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
|
||||||
|
|
||||||
export type GetTemplateWithDetailsByIdOptions = {
|
export type GetTemplateWithDetailsByIdOptions = {
|
||||||
id: number;
|
id: number;
|
||||||
userId: number;
|
userId: number;
|
||||||
@@ -12,7 +10,7 @@ export const getTemplateWithDetailsById = async ({
|
|||||||
id,
|
id,
|
||||||
userId,
|
userId,
|
||||||
}: GetTemplateWithDetailsByIdOptions): Promise<TemplateWithDetails> => {
|
}: GetTemplateWithDetailsByIdOptions): Promise<TemplateWithDetails> => {
|
||||||
const template = await prisma.template.findFirst({
|
return await prisma.template.findFirstOrThrow({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
OR: [
|
OR: [
|
||||||
@@ -38,12 +36,4 @@ export const getTemplateWithDetailsById = async ({
|
|||||||
Field: true,
|
Field: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
|
||||||
message: 'Template not found',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return template;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,17 +40,13 @@ export const toggleTemplateDirectLink = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Template not found');
|
||||||
message: 'Template not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { directLink } = template;
|
const { directLink } = template;
|
||||||
|
|
||||||
if (!directLink) {
|
if (!directLink) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Direct template link not found');
|
||||||
message: 'Direct template link not found',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await prisma.templateDirectLink.update({
|
return await prisma.templateDirectLink.update({
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ export const updateTemplateSettings = async ({
|
|||||||
data,
|
data,
|
||||||
}: UpdateTemplateSettingsOptions) => {
|
}: UpdateTemplateSettingsOptions) => {
|
||||||
if (Object.values(data).length === 0 && Object.keys(meta ?? {}).length === 0) {
|
if (Object.values(data).length === 0 && Object.keys(meta ?? {}).length === 0) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||||
message: 'Missing data to update',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = await prisma.template.findFirstOrThrow({
|
const template = await prisma.template.findFirstOrThrow({
|
||||||
@@ -84,9 +82,10 @@ export const updateTemplateSettings = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!isDocumentEnterprise) {
|
if (!isDocumentEnterprise) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(
|
||||||
message: 'You do not have permission to set the action auth',
|
AppErrorCode.UNAUTHORIZED,
|
||||||
});
|
'You do not have permission to set the action auth',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,11 @@ export const createUser = async ({ name, email, password, signature, url }: Crea
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (urlExists) {
|
if (urlExists) {
|
||||||
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, {
|
throw new AppError(
|
||||||
message: 'Profile username is taken',
|
AppErrorCode.PROFILE_URL_TAKEN,
|
||||||
userMessage: 'The profile username is already taken',
|
'Profile username is taken',
|
||||||
});
|
'The profile username is already taken',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const getUserPublicProfile = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'User not found' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and return the public profile.
|
// Create and return the public profile.
|
||||||
@@ -39,7 +39,7 @@ export const getUserPublicProfile = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Failed to create public profile' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Failed to create public profile');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export type UpdatePublicProfileOptions = {
|
|||||||
|
|
||||||
export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileOptions) => {
|
export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileOptions) => {
|
||||||
if (Object.values(data).length === 0) {
|
if (Object.values(data).length === 0) {
|
||||||
throw new AppError(AppErrorCode.INVALID_BODY, { message: 'Missing data to update' });
|
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { url, bio, enabled } = data;
|
const { url, bio, enabled } = data;
|
||||||
@@ -25,15 +25,13 @@ export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileO
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'User not found' });
|
throw new AppError(AppErrorCode.NOT_FOUND, 'User not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalUrl = url ?? user.url;
|
const finalUrl = url ?? user.url;
|
||||||
|
|
||||||
if (!finalUrl && enabled) {
|
if (!finalUrl && enabled) {
|
||||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
throw new AppError(AppErrorCode.INVALID_REQUEST, 'Cannot enable a profile without a URL');
|
||||||
message: 'Cannot enable a profile without a URL',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
@@ -59,9 +57,7 @@ export const updatePublicProfile = async ({ userId, data }: UpdatePublicProfileO
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (isUrlTakenByAnotherUser || isUrlTakenByAnotherTeam) {
|
if (isUrlTakenByAnotherUser || isUrlTakenByAnotherTeam) {
|
||||||
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, {
|
throw new AppError(AppErrorCode.PROFILE_URL_TAKEN, 'The profile username is already taken');
|
||||||
message: 'The profile username is already taken',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ msgstr "{prefix} hat das Dokument erstellt"
|
|||||||
msgid "{prefix} deleted the document"
|
msgid "{prefix} deleted the document"
|
||||||
msgstr "{prefix} hat das Dokument gelöscht"
|
msgstr "{prefix} hat das Dokument gelöscht"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:335
|
#: packages/lib/utils/document-audit-logs.ts:339
|
||||||
msgid "{prefix} moved the document to team"
|
msgid "{prefix} moved the document to team"
|
||||||
msgstr "{prefix} hat das Dokument ins Team verschoben"
|
msgstr "{prefix} hat das Dokument ins Team verschoben"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:319
|
#: packages/lib/utils/document-audit-logs.ts:323
|
||||||
msgid "{prefix} opened the document"
|
msgid "{prefix} opened the document"
|
||||||
msgstr "{prefix} hat das Dokument geöffnet"
|
msgstr "{prefix} hat das Dokument geöffnet"
|
||||||
|
|
||||||
@@ -151,23 +151,27 @@ msgstr "{prefix} hat ein Feld entfernt"
|
|||||||
msgid "{prefix} removed a recipient"
|
msgid "{prefix} removed a recipient"
|
||||||
msgstr "{prefix} hat einen Empfänger entfernt"
|
msgstr "{prefix} hat einen Empfänger entfernt"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:365
|
#: packages/lib/utils/document-audit-logs.ts:369
|
||||||
msgid "{prefix} resent an email to {0}"
|
msgid "{prefix} resent an email to {0}"
|
||||||
msgstr "{prefix} hat eine E-Mail an {0} erneut gesendet"
|
msgstr "{prefix} hat eine E-Mail an {0} erneut gesendet"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:366
|
#: packages/lib/utils/document-audit-logs.ts:295
|
||||||
|
msgid "{prefix} restored the document"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:370
|
||||||
msgid "{prefix} sent an email to {0}"
|
msgid "{prefix} sent an email to {0}"
|
||||||
msgstr "{prefix} hat eine E-Mail an {0} gesendet"
|
msgstr "{prefix} hat eine E-Mail an {0} gesendet"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:331
|
#: packages/lib/utils/document-audit-logs.ts:335
|
||||||
msgid "{prefix} sent the document"
|
msgid "{prefix} sent the document"
|
||||||
msgstr "{prefix} hat das Dokument gesendet"
|
msgstr "{prefix} hat das Dokument gesendet"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:295
|
#: packages/lib/utils/document-audit-logs.ts:299
|
||||||
msgid "{prefix} signed a field"
|
msgid "{prefix} signed a field"
|
||||||
msgstr "{prefix} hat ein Feld unterschrieben"
|
msgstr "{prefix} hat ein Feld unterschrieben"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:299
|
#: packages/lib/utils/document-audit-logs.ts:303
|
||||||
msgid "{prefix} unsigned a field"
|
msgid "{prefix} unsigned a field"
|
||||||
msgstr "{prefix} hat ein Feld ungültig gemacht"
|
msgstr "{prefix} hat ein Feld ungültig gemacht"
|
||||||
|
|
||||||
@@ -179,27 +183,27 @@ msgstr "{prefix} hat ein Feld aktualisiert"
|
|||||||
msgid "{prefix} updated a recipient"
|
msgid "{prefix} updated a recipient"
|
||||||
msgstr "{prefix} hat einen Empfänger aktualisiert"
|
msgstr "{prefix} hat einen Empfänger aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:315
|
#: packages/lib/utils/document-audit-logs.ts:319
|
||||||
msgid "{prefix} updated the document"
|
msgid "{prefix} updated the document"
|
||||||
msgstr "{prefix} hat das Dokument aktualisiert"
|
msgstr "{prefix} hat das Dokument aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:307
|
#: packages/lib/utils/document-audit-logs.ts:311
|
||||||
msgid "{prefix} updated the document access auth requirements"
|
msgid "{prefix} updated the document access auth requirements"
|
||||||
msgstr "{prefix} hat die Anforderungen an die Dokumentenzugriffsautorisierung aktualisiert"
|
msgstr "{prefix} hat die Anforderungen an die Dokumentenzugriffsautorisierung aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:327
|
#: packages/lib/utils/document-audit-logs.ts:331
|
||||||
msgid "{prefix} updated the document external ID"
|
msgid "{prefix} updated the document external ID"
|
||||||
msgstr "{prefix} hat die externe ID des Dokuments aktualisiert"
|
msgstr "{prefix} hat die externe ID des Dokuments aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:311
|
#: packages/lib/utils/document-audit-logs.ts:315
|
||||||
msgid "{prefix} updated the document signing auth requirements"
|
msgid "{prefix} updated the document signing auth requirements"
|
||||||
msgstr "{prefix} hat die Authentifizierungsanforderungen für die Dokumentenunterzeichnung aktualisiert"
|
msgstr "{prefix} hat die Authentifizierungsanforderungen für die Dokumentenunterzeichnung aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:323
|
#: packages/lib/utils/document-audit-logs.ts:327
|
||||||
msgid "{prefix} updated the document title"
|
msgid "{prefix} updated the document title"
|
||||||
msgstr "{prefix} hat den Titel des Dokuments aktualisiert"
|
msgstr "{prefix} hat den Titel des Dokuments aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:303
|
#: packages/lib/utils/document-audit-logs.ts:307
|
||||||
msgid "{prefix} updated the document visibility"
|
msgid "{prefix} updated the document visibility"
|
||||||
msgstr "{prefix} hat die Sichtbarkeit des Dokuments aktualisiert"
|
msgstr "{prefix} hat die Sichtbarkeit des Dokuments aktualisiert"
|
||||||
|
|
||||||
@@ -227,27 +231,27 @@ msgstr "{teamName} hat Sie eingeladen, {action} {documentName}"
|
|||||||
msgid "{teamName} ownership transfer request"
|
msgid "{teamName} ownership transfer request"
|
||||||
msgstr "Anfrage zur Übertragung des Eigentums von {teamName}"
|
msgstr "Anfrage zur Übertragung des Eigentums von {teamName}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:343
|
#: packages/lib/utils/document-audit-logs.ts:347
|
||||||
msgid "{userName} approved the document"
|
msgid "{userName} approved the document"
|
||||||
msgstr "{userName} hat das Dokument genehmigt"
|
msgstr "{userName} hat das Dokument genehmigt"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:344
|
#: packages/lib/utils/document-audit-logs.ts:348
|
||||||
msgid "{userName} CC'd the document"
|
msgid "{userName} CC'd the document"
|
||||||
msgstr "{userName} hat das Dokument in CC gesetzt"
|
msgstr "{userName} hat das Dokument in CC gesetzt"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:345
|
#: packages/lib/utils/document-audit-logs.ts:349
|
||||||
msgid "{userName} completed their task"
|
msgid "{userName} completed their task"
|
||||||
msgstr "{userName} hat ihre Aufgabe abgeschlossen"
|
msgstr "{userName} hat ihre Aufgabe abgeschlossen"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:355
|
#: packages/lib/utils/document-audit-logs.ts:359
|
||||||
msgid "{userName} rejected the document"
|
msgid "{userName} rejected the document"
|
||||||
msgstr "{userName} hat das Dokument abgelehnt"
|
msgstr "{userName} hat das Dokument abgelehnt"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:341
|
#: packages/lib/utils/document-audit-logs.ts:345
|
||||||
msgid "{userName} signed the document"
|
msgid "{userName} signed the document"
|
||||||
msgstr "{userName} hat das Dokument unterschrieben"
|
msgstr "{userName} hat das Dokument unterschrieben"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:342
|
#: packages/lib/utils/document-audit-logs.ts:346
|
||||||
msgid "{userName} viewed the document"
|
msgid "{userName} viewed the document"
|
||||||
msgstr "{userName} hat das Dokument angesehen"
|
msgstr "{userName} hat das Dokument angesehen"
|
||||||
|
|
||||||
@@ -341,7 +345,7 @@ msgstr "Ein Empfänger wurde entfernt"
|
|||||||
msgid "A recipient was updated"
|
msgid "A recipient was updated"
|
||||||
msgstr "Ein Empfänger wurde aktualisiert"
|
msgstr "Ein Empfänger wurde aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||||
msgstr "Eine Anfrage zur Verwendung Ihrer E-Mail wurde von {0} auf Documenso initiiert"
|
msgstr "Eine Anfrage zur Verwendung Ihrer E-Mail wurde von {0} auf Documenso initiiert"
|
||||||
|
|
||||||
@@ -688,17 +692,17 @@ msgstr "Dokument \"{0}\" - Ablehnung Bestätigt"
|
|||||||
msgid "Document access"
|
msgid "Document access"
|
||||||
msgstr "Dokumentenzugriff"
|
msgstr "Dokumentenzugriff"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:306
|
#: packages/lib/utils/document-audit-logs.ts:310
|
||||||
msgid "Document access auth updated"
|
msgid "Document access auth updated"
|
||||||
msgstr "Die Authentifizierung für den Dokumentenzugriff wurde aktualisiert"
|
msgstr "Die Authentifizierung für den Dokumentenzugriff wurde aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/server-only/document/delete-document.ts:246
|
#: packages/lib/server-only/document/delete-document.ts:256
|
||||||
#: packages/lib/server-only/document/super-delete-document.ts:98
|
#: packages/lib/server-only/document/super-delete-document.ts:98
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Dokument storniert"
|
msgstr "Dokument storniert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:369
|
#: packages/lib/utils/document-audit-logs.ts:373
|
||||||
#: packages/lib/utils/document-audit-logs.ts:370
|
#: packages/lib/utils/document-audit-logs.ts:374
|
||||||
msgid "Document completed"
|
msgid "Document completed"
|
||||||
msgstr "Dokument abgeschlossen"
|
msgstr "Dokument abgeschlossen"
|
||||||
|
|
||||||
@@ -711,7 +715,7 @@ msgid "Document created"
|
|||||||
msgstr "Dokument erstellt"
|
msgstr "Dokument erstellt"
|
||||||
|
|
||||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||||
msgid "Document created from direct template"
|
msgid "Document created from direct template"
|
||||||
msgstr "Dokument erstellt aus direkter Vorlage"
|
msgstr "Dokument erstellt aus direkter Vorlage"
|
||||||
|
|
||||||
@@ -736,15 +740,15 @@ msgstr "Dokument gelöscht!"
|
|||||||
msgid "Document Distribution Method"
|
msgid "Document Distribution Method"
|
||||||
msgstr "Verteilungsmethode für Dokumente"
|
msgstr "Verteilungsmethode für Dokumente"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:326
|
#: packages/lib/utils/document-audit-logs.ts:330
|
||||||
msgid "Document external ID updated"
|
msgid "Document external ID updated"
|
||||||
msgstr "Externe ID des Dokuments aktualisiert"
|
msgstr "Externe ID des Dokuments aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:334
|
#: packages/lib/utils/document-audit-logs.ts:338
|
||||||
msgid "Document moved to team"
|
msgid "Document moved to team"
|
||||||
msgstr "Dokument ins Team verschoben"
|
msgstr "Dokument ins Team verschoben"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:318
|
#: packages/lib/utils/document-audit-logs.ts:322
|
||||||
msgid "Document opened"
|
msgid "Document opened"
|
||||||
msgstr "Dokument geöffnet"
|
msgstr "Dokument geöffnet"
|
||||||
|
|
||||||
@@ -759,23 +763,27 @@ msgstr "Dokument Abgelehnt"
|
|||||||
#~ msgid "Document Rejection Confirmed"
|
#~ msgid "Document Rejection Confirmed"
|
||||||
#~ msgstr "Document Rejection Confirmed"
|
#~ msgstr "Document Rejection Confirmed"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:330
|
#: packages/lib/utils/document-audit-logs.ts:294
|
||||||
|
msgid "Document restored"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:334
|
||||||
msgid "Document sent"
|
msgid "Document sent"
|
||||||
msgstr "Dokument gesendet"
|
msgstr "Dokument gesendet"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:310
|
#: packages/lib/utils/document-audit-logs.ts:314
|
||||||
msgid "Document signing auth updated"
|
msgid "Document signing auth updated"
|
||||||
msgstr "Dokument unterzeichnen Authentifizierung aktualisiert"
|
msgstr "Dokument unterzeichnen Authentifizierung aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:322
|
#: packages/lib/utils/document-audit-logs.ts:326
|
||||||
msgid "Document title updated"
|
msgid "Document title updated"
|
||||||
msgstr "Dokumenttitel aktualisiert"
|
msgstr "Dokumenttitel aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:314
|
#: packages/lib/utils/document-audit-logs.ts:318
|
||||||
msgid "Document updated"
|
msgid "Document updated"
|
||||||
msgstr "Dokument aktualisiert"
|
msgstr "Dokument aktualisiert"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:302
|
#: packages/lib/utils/document-audit-logs.ts:306
|
||||||
msgid "Document visibility updated"
|
msgid "Document visibility updated"
|
||||||
msgstr "Sichtbarkeit des Dokuments aktualisiert"
|
msgstr "Sichtbarkeit des Dokuments aktualisiert"
|
||||||
|
|
||||||
@@ -821,11 +829,11 @@ msgstr "E-Mail ist erforderlich"
|
|||||||
msgid "Email Options"
|
msgid "Email Options"
|
||||||
msgstr "E-Mail-Optionen"
|
msgstr "E-Mail-Optionen"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email resent"
|
msgid "Email resent"
|
||||||
msgstr "E-Mail erneut gesendet"
|
msgstr "E-Mail erneut gesendet"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email sent"
|
msgid "Email sent"
|
||||||
msgstr "E-Mail gesendet"
|
msgstr "E-Mail gesendet"
|
||||||
|
|
||||||
@@ -890,11 +898,11 @@ msgstr "Feldbeschriftung"
|
|||||||
msgid "Field placeholder"
|
msgid "Field placeholder"
|
||||||
msgstr "Feldplatzhalter"
|
msgstr "Feldplatzhalter"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:294
|
#: packages/lib/utils/document-audit-logs.ts:298
|
||||||
msgid "Field signed"
|
msgid "Field signed"
|
||||||
msgstr "Feld unterschrieben"
|
msgstr "Feld unterschrieben"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:298
|
#: packages/lib/utils/document-audit-logs.ts:302
|
||||||
msgid "Field unsigned"
|
msgid "Field unsigned"
|
||||||
msgstr "Feld nicht unterschrieben"
|
msgstr "Feld nicht unterschrieben"
|
||||||
|
|
||||||
@@ -1199,8 +1207,8 @@ msgstr "Grund für die Ablehnung: {rejectionReason}"
|
|||||||
msgid "Receives copy"
|
msgid "Receives copy"
|
||||||
msgstr "Erhält Kopie"
|
msgstr "Erhält Kopie"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:338
|
#: packages/lib/utils/document-audit-logs.ts:342
|
||||||
#: packages/lib/utils/document-audit-logs.ts:353
|
#: packages/lib/utils/document-audit-logs.ts:357
|
||||||
msgid "Recipient"
|
msgid "Recipient"
|
||||||
msgstr "Empfänger"
|
msgstr "Empfänger"
|
||||||
|
|
||||||
@@ -1774,7 +1782,7 @@ msgstr "Du wurdest eingeladen, {0} auf Documenso beizutreten"
|
|||||||
msgid "You have been invited to join the following team"
|
msgid "You have been invited to join the following team"
|
||||||
msgstr "Du wurdest eingeladen, dem folgenden Team beizutreten"
|
msgstr "Du wurdest eingeladen, dem folgenden Team beizutreten"
|
||||||
|
|
||||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||||
msgid "You have been removed from a document"
|
msgid "You have been removed from a document"
|
||||||
msgstr "Du wurdest von einem Dokument entfernt"
|
msgstr "Du wurdest von einem Dokument entfernt"
|
||||||
|
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ msgstr "Bestätigung"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:127
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
||||||
@@ -413,7 +413,7 @@ msgstr "Alle"
|
|||||||
msgid "All documents"
|
msgid "All documents"
|
||||||
msgstr "Alle Dokumente"
|
msgstr "Alle Dokumente"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:40
|
||||||
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
||||||
msgstr "Alle Dokumente wurden verarbeitet. Alle neuen Dokumente, die gesendet oder empfangen werden, werden hier angezeigt."
|
msgstr "Alle Dokumente wurden verarbeitet. Alle neuen Dokumente, die gesendet oder empfangen werden, werden hier angezeigt."
|
||||||
|
|
||||||
@@ -516,7 +516,7 @@ msgstr "Ein Fehler ist aufgetreten, während das direkte Links-Signieren deaktiv
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:107
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:111
|
||||||
msgid "An error occurred while downloading your document."
|
msgid "An error occurred while downloading your document."
|
||||||
msgstr "Ein Fehler ist aufgetreten, während dein Dokument heruntergeladen wurde."
|
msgstr "Ein Fehler ist aufgetreten, während dein Dokument heruntergeladen wurde."
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ msgstr "App-Version"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:150
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||||
msgid "Approve"
|
msgid "Approve"
|
||||||
msgstr "Genehmigen"
|
msgstr "Genehmigen"
|
||||||
@@ -784,6 +784,10 @@ msgstr "Basisdetails"
|
|||||||
msgid "Billing"
|
msgid "Billing"
|
||||||
msgstr "Abrechnung"
|
msgstr "Abrechnung"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:51
|
||||||
|
msgid "Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
||||||
msgid "Branding Preferences"
|
msgid "Branding Preferences"
|
||||||
msgstr "Markenpräferenzen"
|
msgstr "Markenpräferenzen"
|
||||||
@@ -1283,7 +1287,6 @@ msgid "delete"
|
|||||||
msgstr "löschen"
|
msgstr "löschen"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
||||||
@@ -1361,6 +1364,7 @@ msgid "Delete your account and all its contents, including completed documents.
|
|||||||
msgstr "Löschen Sie Ihr Konto und alle Inhalte, einschließlich abgeschlossener Dokumente. Diese Aktion ist irreversibel und führt zur Kündigung Ihres Abonnements, seien Sie also vorsichtig."
|
msgstr "Löschen Sie Ihr Konto und alle Inhalte, einschließlich abgeschlossener Dokumente. Diese Aktion ist irreversibel und führt zur Kündigung Ihres Abonnements, seien Sie also vorsichtig."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:50
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
||||||
msgid "Deleted"
|
msgid "Deleted"
|
||||||
msgstr "Gelöscht"
|
msgstr "Gelöscht"
|
||||||
@@ -1477,6 +1481,10 @@ msgstr "Dokument Alle"
|
|||||||
msgid "Document Approved"
|
msgid "Document Approved"
|
||||||
msgstr "Dokument genehmigt"
|
msgstr "Dokument genehmigt"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:52
|
||||||
|
msgid "Document Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Dokument abgebrochen"
|
msgstr "Dokument abgebrochen"
|
||||||
@@ -1611,7 +1619,7 @@ msgstr "Dokument wird dauerhaft gelöscht"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:108
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||||
#: apps/web/src/app/not-found.tsx:21
|
#: apps/web/src/app/not-found.tsx:21
|
||||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||||
@@ -1641,7 +1649,7 @@ msgstr "Haben Sie kein Konto? <0>Registrieren</0>"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:162
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:166
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
||||||
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
||||||
@@ -1682,7 +1690,7 @@ msgid "Due to an unpaid invoice, your team has been restricted. Please settle th
|
|||||||
msgstr "Aufgrund einer unbezahlten Rechnung wurde Ihrem Team der Zugriff eingeschränkt. Bitte begleichen Sie die Zahlung, um den vollumfänglichen Zugang zu Ihrem Team wiederherzustellen."
|
msgstr "Aufgrund einer unbezahlten Rechnung wurde Ihrem Team der Zugriff eingeschränkt. Bitte begleichen Sie die Zahlung, um den vollumfänglichen Zugang zu Ihrem Team wiederherzustellen."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:167
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:171
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
||||||
@@ -1693,7 +1701,7 @@ msgstr "Duplizieren"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:156
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
||||||
@@ -2012,7 +2020,6 @@ msgstr "So funktioniert es:"
|
|||||||
msgid "Hey I’m Timur"
|
msgid "Hey I’m Timur"
|
||||||
msgstr "Hey, ich bin Timur"
|
msgstr "Hey, ich bin Timur"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
||||||
msgid "Hide"
|
msgid "Hide"
|
||||||
@@ -2063,7 +2070,7 @@ msgstr "Posteingang Dokumente"
|
|||||||
msgid "Include the Signing Certificate in the Document"
|
msgid "Include the Signing Certificate in the Document"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:53
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
||||||
msgid "Information"
|
msgid "Information"
|
||||||
msgstr "Information"
|
msgstr "Information"
|
||||||
@@ -2396,7 +2403,7 @@ msgstr "Dokument in Team verschieben"
|
|||||||
msgid "Move Template to Team"
|
msgid "Move Template to Team"
|
||||||
msgstr "Vorlage in Team verschieben"
|
msgstr "Vorlage in Team verschieben"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:174
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:178
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
||||||
msgid "Move to Team"
|
msgid "Move to Team"
|
||||||
msgstr "In Team verschieben"
|
msgstr "In Team verschieben"
|
||||||
@@ -2460,6 +2467,10 @@ msgstr "Nächstes Feld"
|
|||||||
msgid "No active drafts"
|
msgid "No active drafts"
|
||||||
msgstr "Keine aktiven Entwürfe"
|
msgstr "Keine aktiven Entwürfe"
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
||||||
|
msgid "No documents in the bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
||||||
msgid "No further action is required from you at this time."
|
msgid "No further action is required from you at this time."
|
||||||
msgstr "Es sind derzeit keine weiteren Maßnahmen Ihrerseits erforderlich."
|
msgstr "Es sind derzeit keine weiteren Maßnahmen Ihrerseits erforderlich."
|
||||||
@@ -2516,7 +2527,7 @@ msgid "Not supported"
|
|||||||
msgstr "Nicht unterstützt"
|
msgstr "Nicht unterstützt"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:39
|
||||||
msgid "Nothing to do"
|
msgid "Nothing to do"
|
||||||
msgstr "Nichts zu tun"
|
msgstr "Nichts zu tun"
|
||||||
|
|
||||||
@@ -3206,12 +3217,12 @@ msgid "Setup"
|
|||||||
msgstr "Einrichten"
|
msgstr "Einrichten"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:193
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:207
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr "Teilen"
|
msgstr "Teilen"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:219
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:233
|
||||||
msgid "Share Signing Card"
|
msgid "Share Signing Card"
|
||||||
msgstr "Signaturkarte teilen"
|
msgstr "Signaturkarte teilen"
|
||||||
|
|
||||||
@@ -3233,7 +3244,7 @@ msgstr "Vorlagen in Ihrem Team-Öffentliches Profil anzeigen, damit Ihre Zielgru
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:139
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:143
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||||
@@ -3357,7 +3368,7 @@ msgid "Signing in..."
|
|||||||
msgstr "Anmeldung..."
|
msgstr "Anmeldung..."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:203
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:217
|
||||||
msgid "Signing Links"
|
msgid "Signing Links"
|
||||||
msgstr "Signierlinks"
|
msgstr "Signierlinks"
|
||||||
|
|
||||||
@@ -3388,7 +3399,7 @@ msgstr "Website Einstellungen"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:106
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:110
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
||||||
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
||||||
@@ -3873,6 +3884,10 @@ msgstr "Es gibt derzeit keine aktiven Entwürfe. Sie können ein Dokument hochla
|
|||||||
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
||||||
msgstr "Es gibt noch keine abgeschlossenen Dokumente. Dokumente, die Sie erstellt oder erhalten haben, werden hier angezeigt, sobald sie abgeschlossen sind."
|
msgstr "Es gibt noch keine abgeschlossenen Dokumente. Dokumente, die Sie erstellt oder erhalten haben, werden hier angezeigt, sobald sie abgeschlossen sind."
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
||||||
|
msgid "There are no documents in the bin."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
||||||
msgid "They have permission on your behalf to:"
|
msgid "They have permission on your behalf to:"
|
||||||
msgstr "Sie haben in Ihrem Namen die Erlaubnis, zu:"
|
msgstr "Sie haben in Ihrem Namen die Erlaubnis, zu:"
|
||||||
@@ -4432,7 +4447,7 @@ msgstr "Versionsverlauf"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:132
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:136
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
||||||
msgid "View"
|
msgid "View"
|
||||||
|
|||||||
@@ -130,11 +130,11 @@ msgstr "{prefix} created the document"
|
|||||||
msgid "{prefix} deleted the document"
|
msgid "{prefix} deleted the document"
|
||||||
msgstr "{prefix} deleted the document"
|
msgstr "{prefix} deleted the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:335
|
#: packages/lib/utils/document-audit-logs.ts:339
|
||||||
msgid "{prefix} moved the document to team"
|
msgid "{prefix} moved the document to team"
|
||||||
msgstr "{prefix} moved the document to team"
|
msgstr "{prefix} moved the document to team"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:319
|
#: packages/lib/utils/document-audit-logs.ts:323
|
||||||
msgid "{prefix} opened the document"
|
msgid "{prefix} opened the document"
|
||||||
msgstr "{prefix} opened the document"
|
msgstr "{prefix} opened the document"
|
||||||
|
|
||||||
@@ -146,23 +146,27 @@ msgstr "{prefix} removed a field"
|
|||||||
msgid "{prefix} removed a recipient"
|
msgid "{prefix} removed a recipient"
|
||||||
msgstr "{prefix} removed a recipient"
|
msgstr "{prefix} removed a recipient"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:365
|
#: packages/lib/utils/document-audit-logs.ts:369
|
||||||
msgid "{prefix} resent an email to {0}"
|
msgid "{prefix} resent an email to {0}"
|
||||||
msgstr "{prefix} resent an email to {0}"
|
msgstr "{prefix} resent an email to {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:366
|
#: packages/lib/utils/document-audit-logs.ts:295
|
||||||
|
msgid "{prefix} restored the document"
|
||||||
|
msgstr "{prefix} restored the document"
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:370
|
||||||
msgid "{prefix} sent an email to {0}"
|
msgid "{prefix} sent an email to {0}"
|
||||||
msgstr "{prefix} sent an email to {0}"
|
msgstr "{prefix} sent an email to {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:331
|
#: packages/lib/utils/document-audit-logs.ts:335
|
||||||
msgid "{prefix} sent the document"
|
msgid "{prefix} sent the document"
|
||||||
msgstr "{prefix} sent the document"
|
msgstr "{prefix} sent the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:295
|
#: packages/lib/utils/document-audit-logs.ts:299
|
||||||
msgid "{prefix} signed a field"
|
msgid "{prefix} signed a field"
|
||||||
msgstr "{prefix} signed a field"
|
msgstr "{prefix} signed a field"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:299
|
#: packages/lib/utils/document-audit-logs.ts:303
|
||||||
msgid "{prefix} unsigned a field"
|
msgid "{prefix} unsigned a field"
|
||||||
msgstr "{prefix} unsigned a field"
|
msgstr "{prefix} unsigned a field"
|
||||||
|
|
||||||
@@ -174,27 +178,27 @@ msgstr "{prefix} updated a field"
|
|||||||
msgid "{prefix} updated a recipient"
|
msgid "{prefix} updated a recipient"
|
||||||
msgstr "{prefix} updated a recipient"
|
msgstr "{prefix} updated a recipient"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:315
|
#: packages/lib/utils/document-audit-logs.ts:319
|
||||||
msgid "{prefix} updated the document"
|
msgid "{prefix} updated the document"
|
||||||
msgstr "{prefix} updated the document"
|
msgstr "{prefix} updated the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:307
|
#: packages/lib/utils/document-audit-logs.ts:311
|
||||||
msgid "{prefix} updated the document access auth requirements"
|
msgid "{prefix} updated the document access auth requirements"
|
||||||
msgstr "{prefix} updated the document access auth requirements"
|
msgstr "{prefix} updated the document access auth requirements"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:327
|
#: packages/lib/utils/document-audit-logs.ts:331
|
||||||
msgid "{prefix} updated the document external ID"
|
msgid "{prefix} updated the document external ID"
|
||||||
msgstr "{prefix} updated the document external ID"
|
msgstr "{prefix} updated the document external ID"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:311
|
#: packages/lib/utils/document-audit-logs.ts:315
|
||||||
msgid "{prefix} updated the document signing auth requirements"
|
msgid "{prefix} updated the document signing auth requirements"
|
||||||
msgstr "{prefix} updated the document signing auth requirements"
|
msgstr "{prefix} updated the document signing auth requirements"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:323
|
#: packages/lib/utils/document-audit-logs.ts:327
|
||||||
msgid "{prefix} updated the document title"
|
msgid "{prefix} updated the document title"
|
||||||
msgstr "{prefix} updated the document title"
|
msgstr "{prefix} updated the document title"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:303
|
#: packages/lib/utils/document-audit-logs.ts:307
|
||||||
msgid "{prefix} updated the document visibility"
|
msgid "{prefix} updated the document visibility"
|
||||||
msgstr "{prefix} updated the document visibility"
|
msgstr "{prefix} updated the document visibility"
|
||||||
|
|
||||||
@@ -222,27 +226,27 @@ msgstr "{teamName} has invited you to {action} {documentName}"
|
|||||||
msgid "{teamName} ownership transfer request"
|
msgid "{teamName} ownership transfer request"
|
||||||
msgstr "{teamName} ownership transfer request"
|
msgstr "{teamName} ownership transfer request"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:343
|
#: packages/lib/utils/document-audit-logs.ts:347
|
||||||
msgid "{userName} approved the document"
|
msgid "{userName} approved the document"
|
||||||
msgstr "{userName} approved the document"
|
msgstr "{userName} approved the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:344
|
#: packages/lib/utils/document-audit-logs.ts:348
|
||||||
msgid "{userName} CC'd the document"
|
msgid "{userName} CC'd the document"
|
||||||
msgstr "{userName} CC'd the document"
|
msgstr "{userName} CC'd the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:345
|
#: packages/lib/utils/document-audit-logs.ts:349
|
||||||
msgid "{userName} completed their task"
|
msgid "{userName} completed their task"
|
||||||
msgstr "{userName} completed their task"
|
msgstr "{userName} completed their task"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:355
|
#: packages/lib/utils/document-audit-logs.ts:359
|
||||||
msgid "{userName} rejected the document"
|
msgid "{userName} rejected the document"
|
||||||
msgstr "{userName} rejected the document"
|
msgstr "{userName} rejected the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:341
|
#: packages/lib/utils/document-audit-logs.ts:345
|
||||||
msgid "{userName} signed the document"
|
msgid "{userName} signed the document"
|
||||||
msgstr "{userName} signed the document"
|
msgstr "{userName} signed the document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:342
|
#: packages/lib/utils/document-audit-logs.ts:346
|
||||||
msgid "{userName} viewed the document"
|
msgid "{userName} viewed the document"
|
||||||
msgstr "{userName} viewed the document"
|
msgstr "{userName} viewed the document"
|
||||||
|
|
||||||
@@ -336,7 +340,7 @@ msgstr "A recipient was removed"
|
|||||||
msgid "A recipient was updated"
|
msgid "A recipient was updated"
|
||||||
msgstr "A recipient was updated"
|
msgstr "A recipient was updated"
|
||||||
|
|
||||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||||
msgstr "A request to use your email has been initiated by {0} on Documenso"
|
msgstr "A request to use your email has been initiated by {0} on Documenso"
|
||||||
|
|
||||||
@@ -683,17 +687,17 @@ msgstr "Document \"{0}\" - Rejection Confirmed"
|
|||||||
msgid "Document access"
|
msgid "Document access"
|
||||||
msgstr "Document access"
|
msgstr "Document access"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:306
|
#: packages/lib/utils/document-audit-logs.ts:310
|
||||||
msgid "Document access auth updated"
|
msgid "Document access auth updated"
|
||||||
msgstr "Document access auth updated"
|
msgstr "Document access auth updated"
|
||||||
|
|
||||||
#: packages/lib/server-only/document/delete-document.ts:246
|
#: packages/lib/server-only/document/delete-document.ts:256
|
||||||
#: packages/lib/server-only/document/super-delete-document.ts:98
|
#: packages/lib/server-only/document/super-delete-document.ts:98
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Document Cancelled"
|
msgstr "Document Cancelled"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:369
|
#: packages/lib/utils/document-audit-logs.ts:373
|
||||||
#: packages/lib/utils/document-audit-logs.ts:370
|
#: packages/lib/utils/document-audit-logs.ts:374
|
||||||
msgid "Document completed"
|
msgid "Document completed"
|
||||||
msgstr "Document completed"
|
msgstr "Document completed"
|
||||||
|
|
||||||
@@ -706,7 +710,7 @@ msgid "Document created"
|
|||||||
msgstr "Document created"
|
msgstr "Document created"
|
||||||
|
|
||||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||||
msgid "Document created from direct template"
|
msgid "Document created from direct template"
|
||||||
msgstr "Document created from direct template"
|
msgstr "Document created from direct template"
|
||||||
|
|
||||||
@@ -731,15 +735,15 @@ msgstr "Document Deleted!"
|
|||||||
msgid "Document Distribution Method"
|
msgid "Document Distribution Method"
|
||||||
msgstr "Document Distribution Method"
|
msgstr "Document Distribution Method"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:326
|
#: packages/lib/utils/document-audit-logs.ts:330
|
||||||
msgid "Document external ID updated"
|
msgid "Document external ID updated"
|
||||||
msgstr "Document external ID updated"
|
msgstr "Document external ID updated"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:334
|
#: packages/lib/utils/document-audit-logs.ts:338
|
||||||
msgid "Document moved to team"
|
msgid "Document moved to team"
|
||||||
msgstr "Document moved to team"
|
msgstr "Document moved to team"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:318
|
#: packages/lib/utils/document-audit-logs.ts:322
|
||||||
msgid "Document opened"
|
msgid "Document opened"
|
||||||
msgstr "Document opened"
|
msgstr "Document opened"
|
||||||
|
|
||||||
@@ -754,23 +758,27 @@ msgstr "Document Rejected"
|
|||||||
#~ msgid "Document Rejection Confirmed"
|
#~ msgid "Document Rejection Confirmed"
|
||||||
#~ msgstr "Document Rejection Confirmed"
|
#~ msgstr "Document Rejection Confirmed"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:330
|
#: packages/lib/utils/document-audit-logs.ts:294
|
||||||
|
msgid "Document restored"
|
||||||
|
msgstr "Document restored"
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:334
|
||||||
msgid "Document sent"
|
msgid "Document sent"
|
||||||
msgstr "Document sent"
|
msgstr "Document sent"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:310
|
#: packages/lib/utils/document-audit-logs.ts:314
|
||||||
msgid "Document signing auth updated"
|
msgid "Document signing auth updated"
|
||||||
msgstr "Document signing auth updated"
|
msgstr "Document signing auth updated"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:322
|
#: packages/lib/utils/document-audit-logs.ts:326
|
||||||
msgid "Document title updated"
|
msgid "Document title updated"
|
||||||
msgstr "Document title updated"
|
msgstr "Document title updated"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:314
|
#: packages/lib/utils/document-audit-logs.ts:318
|
||||||
msgid "Document updated"
|
msgid "Document updated"
|
||||||
msgstr "Document updated"
|
msgstr "Document updated"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:302
|
#: packages/lib/utils/document-audit-logs.ts:306
|
||||||
msgid "Document visibility updated"
|
msgid "Document visibility updated"
|
||||||
msgstr "Document visibility updated"
|
msgstr "Document visibility updated"
|
||||||
|
|
||||||
@@ -816,11 +824,11 @@ msgstr "Email is required"
|
|||||||
msgid "Email Options"
|
msgid "Email Options"
|
||||||
msgstr "Email Options"
|
msgstr "Email Options"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email resent"
|
msgid "Email resent"
|
||||||
msgstr "Email resent"
|
msgstr "Email resent"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email sent"
|
msgid "Email sent"
|
||||||
msgstr "Email sent"
|
msgstr "Email sent"
|
||||||
|
|
||||||
@@ -885,11 +893,11 @@ msgstr "Field label"
|
|||||||
msgid "Field placeholder"
|
msgid "Field placeholder"
|
||||||
msgstr "Field placeholder"
|
msgstr "Field placeholder"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:294
|
#: packages/lib/utils/document-audit-logs.ts:298
|
||||||
msgid "Field signed"
|
msgid "Field signed"
|
||||||
msgstr "Field signed"
|
msgstr "Field signed"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:298
|
#: packages/lib/utils/document-audit-logs.ts:302
|
||||||
msgid "Field unsigned"
|
msgid "Field unsigned"
|
||||||
msgstr "Field unsigned"
|
msgstr "Field unsigned"
|
||||||
|
|
||||||
@@ -1194,8 +1202,8 @@ msgstr "Reason for rejection: {rejectionReason}"
|
|||||||
msgid "Receives copy"
|
msgid "Receives copy"
|
||||||
msgstr "Receives copy"
|
msgstr "Receives copy"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:338
|
#: packages/lib/utils/document-audit-logs.ts:342
|
||||||
#: packages/lib/utils/document-audit-logs.ts:353
|
#: packages/lib/utils/document-audit-logs.ts:357
|
||||||
msgid "Recipient"
|
msgid "Recipient"
|
||||||
msgstr "Recipient"
|
msgstr "Recipient"
|
||||||
|
|
||||||
@@ -1769,7 +1777,7 @@ msgstr "You have been invited to join {0} on Documenso"
|
|||||||
msgid "You have been invited to join the following team"
|
msgid "You have been invited to join the following team"
|
||||||
msgstr "You have been invited to join the following team"
|
msgstr "You have been invited to join the following team"
|
||||||
|
|
||||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||||
msgid "You have been removed from a document"
|
msgid "You have been removed from a document"
|
||||||
msgstr "You have been removed from a document"
|
msgstr "You have been removed from a document"
|
||||||
|
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ msgstr "Acknowledgment"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:127
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
||||||
@@ -408,7 +408,7 @@ msgstr "All"
|
|||||||
msgid "All documents"
|
msgid "All documents"
|
||||||
msgstr "All documents"
|
msgstr "All documents"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:40
|
||||||
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
||||||
msgstr "All documents have been processed. Any new documents that are sent or received will show here."
|
msgstr "All documents have been processed. Any new documents that are sent or received will show here."
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ msgstr "An error occurred while disabling direct link signing."
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:107
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:111
|
||||||
msgid "An error occurred while downloading your document."
|
msgid "An error occurred while downloading your document."
|
||||||
msgstr "An error occurred while downloading your document."
|
msgstr "An error occurred while downloading your document."
|
||||||
|
|
||||||
@@ -671,7 +671,7 @@ msgstr "App Version"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:150
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||||
msgid "Approve"
|
msgid "Approve"
|
||||||
msgstr "Approve"
|
msgstr "Approve"
|
||||||
@@ -779,6 +779,10 @@ msgstr "Basic details"
|
|||||||
msgid "Billing"
|
msgid "Billing"
|
||||||
msgstr "Billing"
|
msgstr "Billing"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:51
|
||||||
|
msgid "Bin"
|
||||||
|
msgstr "Bin"
|
||||||
|
|
||||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
||||||
msgid "Branding Preferences"
|
msgid "Branding Preferences"
|
||||||
msgstr "Branding Preferences"
|
msgstr "Branding Preferences"
|
||||||
@@ -1278,7 +1282,6 @@ msgid "delete"
|
|||||||
msgstr "delete"
|
msgstr "delete"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
||||||
@@ -1356,6 +1359,7 @@ msgid "Delete your account and all its contents, including completed documents.
|
|||||||
msgstr "Delete your account and all its contents, including completed documents. This action is irreversible and will cancel your subscription, so proceed with caution."
|
msgstr "Delete your account and all its contents, including completed documents. This action is irreversible and will cancel your subscription, so proceed with caution."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:50
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
||||||
msgid "Deleted"
|
msgid "Deleted"
|
||||||
msgstr "Deleted"
|
msgstr "Deleted"
|
||||||
@@ -1472,6 +1476,10 @@ msgstr "Document All"
|
|||||||
msgid "Document Approved"
|
msgid "Document Approved"
|
||||||
msgstr "Document Approved"
|
msgstr "Document Approved"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:52
|
||||||
|
msgid "Document Bin"
|
||||||
|
msgstr "Document Bin"
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Document Cancelled"
|
msgstr "Document Cancelled"
|
||||||
@@ -1606,7 +1614,7 @@ msgstr "Document will be permanently deleted"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:108
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||||
#: apps/web/src/app/not-found.tsx:21
|
#: apps/web/src/app/not-found.tsx:21
|
||||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||||
@@ -1636,7 +1644,7 @@ msgstr "Don't have an account? <0>Sign up</0>"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:162
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:166
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
||||||
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
||||||
@@ -1677,7 +1685,7 @@ msgid "Due to an unpaid invoice, your team has been restricted. Please settle th
|
|||||||
msgstr "Due to an unpaid invoice, your team has been restricted. Please settle the payment to restore full access to your team."
|
msgstr "Due to an unpaid invoice, your team has been restricted. Please settle the payment to restore full access to your team."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:167
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:171
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
||||||
@@ -1688,7 +1696,7 @@ msgstr "Duplicate"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:156
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
||||||
@@ -2007,7 +2015,6 @@ msgstr "Here's how it works:"
|
|||||||
msgid "Hey I’m Timur"
|
msgid "Hey I’m Timur"
|
||||||
msgstr "Hey I’m Timur"
|
msgstr "Hey I’m Timur"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
||||||
msgid "Hide"
|
msgid "Hide"
|
||||||
@@ -2058,7 +2065,7 @@ msgstr "Inbox documents"
|
|||||||
msgid "Include the Signing Certificate in the Document"
|
msgid "Include the Signing Certificate in the Document"
|
||||||
msgstr "Include the Signing Certificate in the Document"
|
msgstr "Include the Signing Certificate in the Document"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:53
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
||||||
msgid "Information"
|
msgid "Information"
|
||||||
msgstr "Information"
|
msgstr "Information"
|
||||||
@@ -2391,7 +2398,7 @@ msgstr "Move Document to Team"
|
|||||||
msgid "Move Template to Team"
|
msgid "Move Template to Team"
|
||||||
msgstr "Move Template to Team"
|
msgstr "Move Template to Team"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:174
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:178
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
||||||
msgid "Move to Team"
|
msgid "Move to Team"
|
||||||
msgstr "Move to Team"
|
msgstr "Move to Team"
|
||||||
@@ -2455,6 +2462,10 @@ msgstr "Next field"
|
|||||||
msgid "No active drafts"
|
msgid "No active drafts"
|
||||||
msgstr "No active drafts"
|
msgstr "No active drafts"
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
||||||
|
msgid "No documents in the bin"
|
||||||
|
msgstr "No documents in the bin"
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
||||||
msgid "No further action is required from you at this time."
|
msgid "No further action is required from you at this time."
|
||||||
msgstr "No further action is required from you at this time."
|
msgstr "No further action is required from you at this time."
|
||||||
@@ -2511,7 +2522,7 @@ msgid "Not supported"
|
|||||||
msgstr "Not supported"
|
msgstr "Not supported"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:39
|
||||||
msgid "Nothing to do"
|
msgid "Nothing to do"
|
||||||
msgstr "Nothing to do"
|
msgstr "Nothing to do"
|
||||||
|
|
||||||
@@ -3201,12 +3212,12 @@ msgid "Setup"
|
|||||||
msgstr "Setup"
|
msgstr "Setup"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:193
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:207
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr "Share"
|
msgstr "Share"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:219
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:233
|
||||||
msgid "Share Signing Card"
|
msgid "Share Signing Card"
|
||||||
msgstr "Share Signing Card"
|
msgstr "Share Signing Card"
|
||||||
|
|
||||||
@@ -3228,7 +3239,7 @@ msgstr "Show templates in your team public profile for your audience to sign and
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:139
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:143
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||||
@@ -3352,7 +3363,7 @@ msgid "Signing in..."
|
|||||||
msgstr "Signing in..."
|
msgstr "Signing in..."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:203
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:217
|
||||||
msgid "Signing Links"
|
msgid "Signing Links"
|
||||||
msgstr "Signing Links"
|
msgstr "Signing Links"
|
||||||
|
|
||||||
@@ -3383,7 +3394,7 @@ msgstr "Site Settings"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:106
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:110
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
||||||
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
||||||
@@ -3868,6 +3879,10 @@ msgstr "There are no active drafts at the current moment. You can upload a docum
|
|||||||
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
||||||
msgstr "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
msgstr "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
||||||
|
msgid "There are no documents in the bin."
|
||||||
|
msgstr "There are no documents in the bin."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
||||||
msgid "They have permission on your behalf to:"
|
msgid "They have permission on your behalf to:"
|
||||||
msgstr "They have permission on your behalf to:"
|
msgstr "They have permission on your behalf to:"
|
||||||
@@ -4427,7 +4442,7 @@ msgstr "Version History"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:132
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:136
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
||||||
msgid "View"
|
msgid "View"
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ msgstr "{prefix} creó el documento"
|
|||||||
msgid "{prefix} deleted the document"
|
msgid "{prefix} deleted the document"
|
||||||
msgstr "{prefix} eliminó el documento"
|
msgstr "{prefix} eliminó el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:335
|
#: packages/lib/utils/document-audit-logs.ts:339
|
||||||
msgid "{prefix} moved the document to team"
|
msgid "{prefix} moved the document to team"
|
||||||
msgstr "{prefix} movió el documento al equipo"
|
msgstr "{prefix} movió el documento al equipo"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:319
|
#: packages/lib/utils/document-audit-logs.ts:323
|
||||||
msgid "{prefix} opened the document"
|
msgid "{prefix} opened the document"
|
||||||
msgstr "{prefix} abrió el documento"
|
msgstr "{prefix} abrió el documento"
|
||||||
|
|
||||||
@@ -151,23 +151,27 @@ msgstr "{prefix} eliminó un campo"
|
|||||||
msgid "{prefix} removed a recipient"
|
msgid "{prefix} removed a recipient"
|
||||||
msgstr "{prefix} eliminó un destinatario"
|
msgstr "{prefix} eliminó un destinatario"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:365
|
#: packages/lib/utils/document-audit-logs.ts:369
|
||||||
msgid "{prefix} resent an email to {0}"
|
msgid "{prefix} resent an email to {0}"
|
||||||
msgstr "{prefix} reenviaron un correo electrónico a {0}"
|
msgstr "{prefix} reenviaron un correo electrónico a {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:366
|
#: packages/lib/utils/document-audit-logs.ts:295
|
||||||
|
msgid "{prefix} restored the document"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:370
|
||||||
msgid "{prefix} sent an email to {0}"
|
msgid "{prefix} sent an email to {0}"
|
||||||
msgstr "{prefix} envió un correo electrónico a {0}"
|
msgstr "{prefix} envió un correo electrónico a {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:331
|
#: packages/lib/utils/document-audit-logs.ts:335
|
||||||
msgid "{prefix} sent the document"
|
msgid "{prefix} sent the document"
|
||||||
msgstr "{prefix} envió el documento"
|
msgstr "{prefix} envió el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:295
|
#: packages/lib/utils/document-audit-logs.ts:299
|
||||||
msgid "{prefix} signed a field"
|
msgid "{prefix} signed a field"
|
||||||
msgstr "{prefix} firmó un campo"
|
msgstr "{prefix} firmó un campo"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:299
|
#: packages/lib/utils/document-audit-logs.ts:303
|
||||||
msgid "{prefix} unsigned a field"
|
msgid "{prefix} unsigned a field"
|
||||||
msgstr "{prefix} no firmó un campo"
|
msgstr "{prefix} no firmó un campo"
|
||||||
|
|
||||||
@@ -179,27 +183,27 @@ msgstr "{prefix} actualizó un campo"
|
|||||||
msgid "{prefix} updated a recipient"
|
msgid "{prefix} updated a recipient"
|
||||||
msgstr "{prefix} actualizó un destinatario"
|
msgstr "{prefix} actualizó un destinatario"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:315
|
#: packages/lib/utils/document-audit-logs.ts:319
|
||||||
msgid "{prefix} updated the document"
|
msgid "{prefix} updated the document"
|
||||||
msgstr "{prefix} actualizó el documento"
|
msgstr "{prefix} actualizó el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:307
|
#: packages/lib/utils/document-audit-logs.ts:311
|
||||||
msgid "{prefix} updated the document access auth requirements"
|
msgid "{prefix} updated the document access auth requirements"
|
||||||
msgstr "{prefix} actualizó los requisitos de autorización de acceso al documento"
|
msgstr "{prefix} actualizó los requisitos de autorización de acceso al documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:327
|
#: packages/lib/utils/document-audit-logs.ts:331
|
||||||
msgid "{prefix} updated the document external ID"
|
msgid "{prefix} updated the document external ID"
|
||||||
msgstr "{prefix} actualizó el ID externo del documento"
|
msgstr "{prefix} actualizó el ID externo del documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:311
|
#: packages/lib/utils/document-audit-logs.ts:315
|
||||||
msgid "{prefix} updated the document signing auth requirements"
|
msgid "{prefix} updated the document signing auth requirements"
|
||||||
msgstr "{prefix} actualizó los requisitos de autenticación para la firma del documento"
|
msgstr "{prefix} actualizó los requisitos de autenticación para la firma del documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:323
|
#: packages/lib/utils/document-audit-logs.ts:327
|
||||||
msgid "{prefix} updated the document title"
|
msgid "{prefix} updated the document title"
|
||||||
msgstr "{prefix} actualizó el título del documento"
|
msgstr "{prefix} actualizó el título del documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:303
|
#: packages/lib/utils/document-audit-logs.ts:307
|
||||||
msgid "{prefix} updated the document visibility"
|
msgid "{prefix} updated the document visibility"
|
||||||
msgstr "{prefix} actualizó la visibilidad del documento"
|
msgstr "{prefix} actualizó la visibilidad del documento"
|
||||||
|
|
||||||
@@ -227,27 +231,27 @@ msgstr "{teamName} te ha invitado a {action} {documentName}"
|
|||||||
msgid "{teamName} ownership transfer request"
|
msgid "{teamName} ownership transfer request"
|
||||||
msgstr "solicitud de transferencia de propiedad de {teamName}"
|
msgstr "solicitud de transferencia de propiedad de {teamName}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:343
|
#: packages/lib/utils/document-audit-logs.ts:347
|
||||||
msgid "{userName} approved the document"
|
msgid "{userName} approved the document"
|
||||||
msgstr "{userName} aprobó el documento"
|
msgstr "{userName} aprobó el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:344
|
#: packages/lib/utils/document-audit-logs.ts:348
|
||||||
msgid "{userName} CC'd the document"
|
msgid "{userName} CC'd the document"
|
||||||
msgstr "{userName} envió una copia del documento"
|
msgstr "{userName} envió una copia del documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:345
|
#: packages/lib/utils/document-audit-logs.ts:349
|
||||||
msgid "{userName} completed their task"
|
msgid "{userName} completed their task"
|
||||||
msgstr "{userName} completó su tarea"
|
msgstr "{userName} completó su tarea"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:355
|
#: packages/lib/utils/document-audit-logs.ts:359
|
||||||
msgid "{userName} rejected the document"
|
msgid "{userName} rejected the document"
|
||||||
msgstr "{userName} rechazó el documento"
|
msgstr "{userName} rechazó el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:341
|
#: packages/lib/utils/document-audit-logs.ts:345
|
||||||
msgid "{userName} signed the document"
|
msgid "{userName} signed the document"
|
||||||
msgstr "{userName} firmó el documento"
|
msgstr "{userName} firmó el documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:342
|
#: packages/lib/utils/document-audit-logs.ts:346
|
||||||
msgid "{userName} viewed the document"
|
msgid "{userName} viewed the document"
|
||||||
msgstr "{userName} vio el documento"
|
msgstr "{userName} vio el documento"
|
||||||
|
|
||||||
@@ -341,7 +345,7 @@ msgstr "Se eliminó un destinatario"
|
|||||||
msgid "A recipient was updated"
|
msgid "A recipient was updated"
|
||||||
msgstr "Se actualizó un destinatario"
|
msgstr "Se actualizó un destinatario"
|
||||||
|
|
||||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||||
msgstr "Se ha iniciado una solicitud para usar tu correo electrónico por {0} en Documenso"
|
msgstr "Se ha iniciado una solicitud para usar tu correo electrónico por {0} en Documenso"
|
||||||
|
|
||||||
@@ -688,17 +692,17 @@ msgstr "Documento \"{0}\" - Rechazo confirmado"
|
|||||||
msgid "Document access"
|
msgid "Document access"
|
||||||
msgstr "Acceso al documento"
|
msgstr "Acceso al documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:306
|
#: packages/lib/utils/document-audit-logs.ts:310
|
||||||
msgid "Document access auth updated"
|
msgid "Document access auth updated"
|
||||||
msgstr "Se actualizó la autenticación de acceso al documento"
|
msgstr "Se actualizó la autenticación de acceso al documento"
|
||||||
|
|
||||||
#: packages/lib/server-only/document/delete-document.ts:246
|
#: packages/lib/server-only/document/delete-document.ts:256
|
||||||
#: packages/lib/server-only/document/super-delete-document.ts:98
|
#: packages/lib/server-only/document/super-delete-document.ts:98
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Documento cancelado"
|
msgstr "Documento cancelado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:369
|
#: packages/lib/utils/document-audit-logs.ts:373
|
||||||
#: packages/lib/utils/document-audit-logs.ts:370
|
#: packages/lib/utils/document-audit-logs.ts:374
|
||||||
msgid "Document completed"
|
msgid "Document completed"
|
||||||
msgstr "Documento completado"
|
msgstr "Documento completado"
|
||||||
|
|
||||||
@@ -711,7 +715,7 @@ msgid "Document created"
|
|||||||
msgstr "Documento creado"
|
msgstr "Documento creado"
|
||||||
|
|
||||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||||
msgid "Document created from direct template"
|
msgid "Document created from direct template"
|
||||||
msgstr "Documento creado a partir de plantilla directa"
|
msgstr "Documento creado a partir de plantilla directa"
|
||||||
|
|
||||||
@@ -736,15 +740,15 @@ msgstr "¡Documento eliminado!"
|
|||||||
msgid "Document Distribution Method"
|
msgid "Document Distribution Method"
|
||||||
msgstr "Método de distribución de documentos"
|
msgstr "Método de distribución de documentos"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:326
|
#: packages/lib/utils/document-audit-logs.ts:330
|
||||||
msgid "Document external ID updated"
|
msgid "Document external ID updated"
|
||||||
msgstr "ID externo del documento actualizado"
|
msgstr "ID externo del documento actualizado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:334
|
#: packages/lib/utils/document-audit-logs.ts:338
|
||||||
msgid "Document moved to team"
|
msgid "Document moved to team"
|
||||||
msgstr "Documento movido al equipo"
|
msgstr "Documento movido al equipo"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:318
|
#: packages/lib/utils/document-audit-logs.ts:322
|
||||||
msgid "Document opened"
|
msgid "Document opened"
|
||||||
msgstr "Documento abierto"
|
msgstr "Documento abierto"
|
||||||
|
|
||||||
@@ -759,23 +763,27 @@ msgstr "Documento Rechazado"
|
|||||||
#~ msgid "Document Rejection Confirmed"
|
#~ msgid "Document Rejection Confirmed"
|
||||||
#~ msgstr "Document Rejection Confirmed"
|
#~ msgstr "Document Rejection Confirmed"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:330
|
#: packages/lib/utils/document-audit-logs.ts:294
|
||||||
|
msgid "Document restored"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:334
|
||||||
msgid "Document sent"
|
msgid "Document sent"
|
||||||
msgstr "Documento enviado"
|
msgstr "Documento enviado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:310
|
#: packages/lib/utils/document-audit-logs.ts:314
|
||||||
msgid "Document signing auth updated"
|
msgid "Document signing auth updated"
|
||||||
msgstr "Se actualizó la autenticación de firma del documento"
|
msgstr "Se actualizó la autenticación de firma del documento"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:322
|
#: packages/lib/utils/document-audit-logs.ts:326
|
||||||
msgid "Document title updated"
|
msgid "Document title updated"
|
||||||
msgstr "Título del documento actualizado"
|
msgstr "Título del documento actualizado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:314
|
#: packages/lib/utils/document-audit-logs.ts:318
|
||||||
msgid "Document updated"
|
msgid "Document updated"
|
||||||
msgstr "Documento actualizado"
|
msgstr "Documento actualizado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:302
|
#: packages/lib/utils/document-audit-logs.ts:306
|
||||||
msgid "Document visibility updated"
|
msgid "Document visibility updated"
|
||||||
msgstr "Visibilidad del documento actualizada"
|
msgstr "Visibilidad del documento actualizada"
|
||||||
|
|
||||||
@@ -821,11 +829,11 @@ msgstr "Se requiere email"
|
|||||||
msgid "Email Options"
|
msgid "Email Options"
|
||||||
msgstr "Opciones de correo electrónico"
|
msgstr "Opciones de correo electrónico"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email resent"
|
msgid "Email resent"
|
||||||
msgstr "Correo electrónico reeenviado"
|
msgstr "Correo electrónico reeenviado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email sent"
|
msgid "Email sent"
|
||||||
msgstr "Correo electrónico enviado"
|
msgstr "Correo electrónico enviado"
|
||||||
|
|
||||||
@@ -890,11 +898,11 @@ msgstr "Etiqueta de campo"
|
|||||||
msgid "Field placeholder"
|
msgid "Field placeholder"
|
||||||
msgstr "Marcador de posición de campo"
|
msgstr "Marcador de posición de campo"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:294
|
#: packages/lib/utils/document-audit-logs.ts:298
|
||||||
msgid "Field signed"
|
msgid "Field signed"
|
||||||
msgstr "Campo firmado"
|
msgstr "Campo firmado"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:298
|
#: packages/lib/utils/document-audit-logs.ts:302
|
||||||
msgid "Field unsigned"
|
msgid "Field unsigned"
|
||||||
msgstr "Campo no firmado"
|
msgstr "Campo no firmado"
|
||||||
|
|
||||||
@@ -1199,8 +1207,8 @@ msgstr "Razón del rechazo: {rejectionReason}"
|
|||||||
msgid "Receives copy"
|
msgid "Receives copy"
|
||||||
msgstr "Recibe copia"
|
msgstr "Recibe copia"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:338
|
#: packages/lib/utils/document-audit-logs.ts:342
|
||||||
#: packages/lib/utils/document-audit-logs.ts:353
|
#: packages/lib/utils/document-audit-logs.ts:357
|
||||||
msgid "Recipient"
|
msgid "Recipient"
|
||||||
msgstr "Destinatario"
|
msgstr "Destinatario"
|
||||||
|
|
||||||
@@ -1774,7 +1782,7 @@ msgstr "Te han invitado a unirte a {0} en Documenso"
|
|||||||
msgid "You have been invited to join the following team"
|
msgid "You have been invited to join the following team"
|
||||||
msgstr "Te han invitado a unirte al siguiente equipo"
|
msgstr "Te han invitado a unirte al siguiente equipo"
|
||||||
|
|
||||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||||
msgid "You have been removed from a document"
|
msgid "You have been removed from a document"
|
||||||
msgstr "Te han eliminado de un documento"
|
msgstr "Te han eliminado de un documento"
|
||||||
|
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ msgstr "Reconocimiento"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:127
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
||||||
@@ -413,7 +413,7 @@ msgstr "Todos"
|
|||||||
msgid "All documents"
|
msgid "All documents"
|
||||||
msgstr "Todos los documentos"
|
msgstr "Todos los documentos"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:40
|
||||||
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
||||||
msgstr "Todos los documentos han sido procesados. Cualquier nuevo documento que se envíe o reciba aparecerá aquí."
|
msgstr "Todos los documentos han sido procesados. Cualquier nuevo documento que se envíe o reciba aparecerá aquí."
|
||||||
|
|
||||||
@@ -516,7 +516,7 @@ msgstr "Ocurrió un error al desactivar la firma de enlace directo."
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:107
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:111
|
||||||
msgid "An error occurred while downloading your document."
|
msgid "An error occurred while downloading your document."
|
||||||
msgstr "Ocurrió un error al descargar tu documento."
|
msgstr "Ocurrió un error al descargar tu documento."
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ msgstr "Versión de la Aplicación"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:150
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||||
msgid "Approve"
|
msgid "Approve"
|
||||||
msgstr "Aprobar"
|
msgstr "Aprobar"
|
||||||
@@ -784,6 +784,10 @@ msgstr "Detalles básicos"
|
|||||||
msgid "Billing"
|
msgid "Billing"
|
||||||
msgstr "Facturación"
|
msgstr "Facturación"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:51
|
||||||
|
msgid "Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
||||||
msgid "Branding Preferences"
|
msgid "Branding Preferences"
|
||||||
msgstr "Preferencias de marca"
|
msgstr "Preferencias de marca"
|
||||||
@@ -1283,7 +1287,6 @@ msgid "delete"
|
|||||||
msgstr "eliminar"
|
msgstr "eliminar"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
||||||
@@ -1361,6 +1364,7 @@ msgid "Delete your account and all its contents, including completed documents.
|
|||||||
msgstr "Eliminar su cuenta y todo su contenido, incluidos documentos completados. Esta acción es irreversible y cancelará su suscripción, así que proceda con cuidado."
|
msgstr "Eliminar su cuenta y todo su contenido, incluidos documentos completados. Esta acción es irreversible y cancelará su suscripción, así que proceda con cuidado."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:50
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
||||||
msgid "Deleted"
|
msgid "Deleted"
|
||||||
msgstr "Eliminado"
|
msgstr "Eliminado"
|
||||||
@@ -1477,6 +1481,10 @@ msgstr "Documentar Todo"
|
|||||||
msgid "Document Approved"
|
msgid "Document Approved"
|
||||||
msgstr "Documento Aprobado"
|
msgstr "Documento Aprobado"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:52
|
||||||
|
msgid "Document Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Documento Cancelado"
|
msgstr "Documento Cancelado"
|
||||||
@@ -1611,7 +1619,7 @@ msgstr "El documento será eliminado permanentemente"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:108
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||||
#: apps/web/src/app/not-found.tsx:21
|
#: apps/web/src/app/not-found.tsx:21
|
||||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||||
@@ -1641,7 +1649,7 @@ msgstr "¿No tienes una cuenta? <0>Regístrate</0>"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:162
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:166
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
||||||
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
||||||
@@ -1682,7 +1690,7 @@ msgid "Due to an unpaid invoice, your team has been restricted. Please settle th
|
|||||||
msgstr "Debido a una factura impaga, tu equipo ha sido restringido. Realiza el pago para restaurar el acceso completo a tu equipo."
|
msgstr "Debido a una factura impaga, tu equipo ha sido restringido. Realiza el pago para restaurar el acceso completo a tu equipo."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:167
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:171
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
||||||
@@ -1693,7 +1701,7 @@ msgstr "Duplicar"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:156
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
||||||
@@ -2012,7 +2020,6 @@ msgstr "Así es como funciona:"
|
|||||||
msgid "Hey I’m Timur"
|
msgid "Hey I’m Timur"
|
||||||
msgstr "Hola, soy Timur"
|
msgstr "Hola, soy Timur"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
||||||
msgid "Hide"
|
msgid "Hide"
|
||||||
@@ -2063,7 +2070,7 @@ msgstr "Documentos en bandeja de entrada"
|
|||||||
msgid "Include the Signing Certificate in the Document"
|
msgid "Include the Signing Certificate in the Document"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:53
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
||||||
msgid "Information"
|
msgid "Information"
|
||||||
msgstr "Información"
|
msgstr "Información"
|
||||||
@@ -2396,7 +2403,7 @@ msgstr "Mover documento al equipo"
|
|||||||
msgid "Move Template to Team"
|
msgid "Move Template to Team"
|
||||||
msgstr "Mover plantilla al equipo"
|
msgstr "Mover plantilla al equipo"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:174
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:178
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
||||||
msgid "Move to Team"
|
msgid "Move to Team"
|
||||||
msgstr "Mover al equipo"
|
msgstr "Mover al equipo"
|
||||||
@@ -2460,6 +2467,10 @@ msgstr "Siguiente campo"
|
|||||||
msgid "No active drafts"
|
msgid "No active drafts"
|
||||||
msgstr "No hay borradores activos"
|
msgstr "No hay borradores activos"
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
||||||
|
msgid "No documents in the bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
||||||
msgid "No further action is required from you at this time."
|
msgid "No further action is required from you at this time."
|
||||||
msgstr "No further action is required from you at this time."
|
msgstr "No further action is required from you at this time."
|
||||||
@@ -2516,7 +2527,7 @@ msgid "Not supported"
|
|||||||
msgstr "No soportado"
|
msgstr "No soportado"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:39
|
||||||
msgid "Nothing to do"
|
msgid "Nothing to do"
|
||||||
msgstr "Nada que hacer"
|
msgstr "Nada que hacer"
|
||||||
|
|
||||||
@@ -3206,12 +3217,12 @@ msgid "Setup"
|
|||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:193
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:207
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr "Compartir"
|
msgstr "Compartir"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:219
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:233
|
||||||
msgid "Share Signing Card"
|
msgid "Share Signing Card"
|
||||||
msgstr "Compartir tarjeta de firma"
|
msgstr "Compartir tarjeta de firma"
|
||||||
|
|
||||||
@@ -3233,7 +3244,7 @@ msgstr "Mostrar plantillas en el perfil público de tu equipo para que tu audien
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:139
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:143
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||||
@@ -3357,7 +3368,7 @@ msgid "Signing in..."
|
|||||||
msgstr "Iniciando sesión..."
|
msgstr "Iniciando sesión..."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:203
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:217
|
||||||
msgid "Signing Links"
|
msgid "Signing Links"
|
||||||
msgstr "Enlaces de firma"
|
msgstr "Enlaces de firma"
|
||||||
|
|
||||||
@@ -3388,7 +3399,7 @@ msgstr "Configuraciones del sitio"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:106
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:110
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
||||||
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
||||||
@@ -3873,6 +3884,10 @@ msgstr "No hay borradores activos en este momento. Puedes subir un documento par
|
|||||||
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
||||||
msgstr "Aún no hay documentos completados. Los documentos que hayas creado o recibido aparecerán aquí una vez completados."
|
msgstr "Aún no hay documentos completados. Los documentos que hayas creado o recibido aparecerán aquí una vez completados."
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
||||||
|
msgid "There are no documents in the bin."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
||||||
msgid "They have permission on your behalf to:"
|
msgid "They have permission on your behalf to:"
|
||||||
msgstr "Tienen permiso en tu nombre para:"
|
msgstr "Tienen permiso en tu nombre para:"
|
||||||
@@ -4432,7 +4447,7 @@ msgstr "Historial de Versiones"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:132
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:136
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
||||||
msgid "View"
|
msgid "View"
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ msgstr "{prefix} a créé le document"
|
|||||||
msgid "{prefix} deleted the document"
|
msgid "{prefix} deleted the document"
|
||||||
msgstr "{prefix} a supprimé le document"
|
msgstr "{prefix} a supprimé le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:335
|
#: packages/lib/utils/document-audit-logs.ts:339
|
||||||
msgid "{prefix} moved the document to team"
|
msgid "{prefix} moved the document to team"
|
||||||
msgstr "{prefix} a déplacé le document vers l'équipe"
|
msgstr "{prefix} a déplacé le document vers l'équipe"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:319
|
#: packages/lib/utils/document-audit-logs.ts:323
|
||||||
msgid "{prefix} opened the document"
|
msgid "{prefix} opened the document"
|
||||||
msgstr "{prefix} a ouvert le document"
|
msgstr "{prefix} a ouvert le document"
|
||||||
|
|
||||||
@@ -151,23 +151,27 @@ msgstr "{prefix} a supprimé un champ"
|
|||||||
msgid "{prefix} removed a recipient"
|
msgid "{prefix} removed a recipient"
|
||||||
msgstr "{prefix} a supprimé un destinataire"
|
msgstr "{prefix} a supprimé un destinataire"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:365
|
#: packages/lib/utils/document-audit-logs.ts:369
|
||||||
msgid "{prefix} resent an email to {0}"
|
msgid "{prefix} resent an email to {0}"
|
||||||
msgstr "{prefix} a renvoyé un e-mail à {0}"
|
msgstr "{prefix} a renvoyé un e-mail à {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:366
|
#: packages/lib/utils/document-audit-logs.ts:295
|
||||||
|
msgid "{prefix} restored the document"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:370
|
||||||
msgid "{prefix} sent an email to {0}"
|
msgid "{prefix} sent an email to {0}"
|
||||||
msgstr "{prefix} a envoyé un email à {0}"
|
msgstr "{prefix} a envoyé un email à {0}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:331
|
#: packages/lib/utils/document-audit-logs.ts:335
|
||||||
msgid "{prefix} sent the document"
|
msgid "{prefix} sent the document"
|
||||||
msgstr "{prefix} a envoyé le document"
|
msgstr "{prefix} a envoyé le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:295
|
#: packages/lib/utils/document-audit-logs.ts:299
|
||||||
msgid "{prefix} signed a field"
|
msgid "{prefix} signed a field"
|
||||||
msgstr "{prefix} a signé un champ"
|
msgstr "{prefix} a signé un champ"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:299
|
#: packages/lib/utils/document-audit-logs.ts:303
|
||||||
msgid "{prefix} unsigned a field"
|
msgid "{prefix} unsigned a field"
|
||||||
msgstr "{prefix} n'a pas signé un champ"
|
msgstr "{prefix} n'a pas signé un champ"
|
||||||
|
|
||||||
@@ -179,27 +183,27 @@ msgstr "{prefix} a mis à jour un champ"
|
|||||||
msgid "{prefix} updated a recipient"
|
msgid "{prefix} updated a recipient"
|
||||||
msgstr "{prefix} a mis à jour un destinataire"
|
msgstr "{prefix} a mis à jour un destinataire"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:315
|
#: packages/lib/utils/document-audit-logs.ts:319
|
||||||
msgid "{prefix} updated the document"
|
msgid "{prefix} updated the document"
|
||||||
msgstr "{prefix} a mis à jour le document"
|
msgstr "{prefix} a mis à jour le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:307
|
#: packages/lib/utils/document-audit-logs.ts:311
|
||||||
msgid "{prefix} updated the document access auth requirements"
|
msgid "{prefix} updated the document access auth requirements"
|
||||||
msgstr "{prefix} a mis à jour les exigences d'authentification d'accès au document"
|
msgstr "{prefix} a mis à jour les exigences d'authentification d'accès au document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:327
|
#: packages/lib/utils/document-audit-logs.ts:331
|
||||||
msgid "{prefix} updated the document external ID"
|
msgid "{prefix} updated the document external ID"
|
||||||
msgstr "{prefix} a mis à jour l'ID externe du document"
|
msgstr "{prefix} a mis à jour l'ID externe du document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:311
|
#: packages/lib/utils/document-audit-logs.ts:315
|
||||||
msgid "{prefix} updated the document signing auth requirements"
|
msgid "{prefix} updated the document signing auth requirements"
|
||||||
msgstr "{prefix} a mis à jour les exigences d'authentification pour la signature du document"
|
msgstr "{prefix} a mis à jour les exigences d'authentification pour la signature du document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:323
|
#: packages/lib/utils/document-audit-logs.ts:327
|
||||||
msgid "{prefix} updated the document title"
|
msgid "{prefix} updated the document title"
|
||||||
msgstr "{prefix} a mis à jour le titre du document"
|
msgstr "{prefix} a mis à jour le titre du document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:303
|
#: packages/lib/utils/document-audit-logs.ts:307
|
||||||
msgid "{prefix} updated the document visibility"
|
msgid "{prefix} updated the document visibility"
|
||||||
msgstr "{prefix} a mis à jour la visibilité du document"
|
msgstr "{prefix} a mis à jour la visibilité du document"
|
||||||
|
|
||||||
@@ -227,27 +231,27 @@ msgstr "{teamName} vous a invité à {action} {documentName}"
|
|||||||
msgid "{teamName} ownership transfer request"
|
msgid "{teamName} ownership transfer request"
|
||||||
msgstr "Demande de transfert de propriété de {teamName}"
|
msgstr "Demande de transfert de propriété de {teamName}"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:343
|
#: packages/lib/utils/document-audit-logs.ts:347
|
||||||
msgid "{userName} approved the document"
|
msgid "{userName} approved the document"
|
||||||
msgstr "{userName} a approuvé le document"
|
msgstr "{userName} a approuvé le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:344
|
#: packages/lib/utils/document-audit-logs.ts:348
|
||||||
msgid "{userName} CC'd the document"
|
msgid "{userName} CC'd the document"
|
||||||
msgstr "{userName} a mis en copie le document"
|
msgstr "{userName} a mis en copie le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:345
|
#: packages/lib/utils/document-audit-logs.ts:349
|
||||||
msgid "{userName} completed their task"
|
msgid "{userName} completed their task"
|
||||||
msgstr "{userName} a complété sa tâche"
|
msgstr "{userName} a complété sa tâche"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:355
|
#: packages/lib/utils/document-audit-logs.ts:359
|
||||||
msgid "{userName} rejected the document"
|
msgid "{userName} rejected the document"
|
||||||
msgstr "{userName} a rejeté le document"
|
msgstr "{userName} a rejeté le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:341
|
#: packages/lib/utils/document-audit-logs.ts:345
|
||||||
msgid "{userName} signed the document"
|
msgid "{userName} signed the document"
|
||||||
msgstr "{userName} a signé le document"
|
msgstr "{userName} a signé le document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:342
|
#: packages/lib/utils/document-audit-logs.ts:346
|
||||||
msgid "{userName} viewed the document"
|
msgid "{userName} viewed the document"
|
||||||
msgstr "{userName} a consulté le document"
|
msgstr "{userName} a consulté le document"
|
||||||
|
|
||||||
@@ -341,7 +345,7 @@ msgstr "Un destinataire a été supprimé"
|
|||||||
msgid "A recipient was updated"
|
msgid "A recipient was updated"
|
||||||
msgstr "Un destinataire a été mis à jour"
|
msgstr "Un destinataire a été mis à jour"
|
||||||
|
|
||||||
#: packages/lib/server-only/team/create-team-email-verification.ts:159
|
#: packages/lib/server-only/team/create-team-email-verification.ts:156
|
||||||
msgid "A request to use your email has been initiated by {0} on Documenso"
|
msgid "A request to use your email has been initiated by {0} on Documenso"
|
||||||
msgstr "Une demande d'utilisation de votre e-mail a été initiée par {0} sur Documenso"
|
msgstr "Une demande d'utilisation de votre e-mail a été initiée par {0} sur Documenso"
|
||||||
|
|
||||||
@@ -688,17 +692,17 @@ msgstr "Document \"{0}\" - Rejet Confirmé"
|
|||||||
msgid "Document access"
|
msgid "Document access"
|
||||||
msgstr "Accès au document"
|
msgstr "Accès au document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:306
|
#: packages/lib/utils/document-audit-logs.ts:310
|
||||||
msgid "Document access auth updated"
|
msgid "Document access auth updated"
|
||||||
msgstr "L'authentification d'accès au document a été mise à jour"
|
msgstr "L'authentification d'accès au document a été mise à jour"
|
||||||
|
|
||||||
#: packages/lib/server-only/document/delete-document.ts:246
|
#: packages/lib/server-only/document/delete-document.ts:256
|
||||||
#: packages/lib/server-only/document/super-delete-document.ts:98
|
#: packages/lib/server-only/document/super-delete-document.ts:98
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Document Annulé"
|
msgstr "Document Annulé"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:369
|
#: packages/lib/utils/document-audit-logs.ts:373
|
||||||
#: packages/lib/utils/document-audit-logs.ts:370
|
#: packages/lib/utils/document-audit-logs.ts:374
|
||||||
msgid "Document completed"
|
msgid "Document completed"
|
||||||
msgstr "Document terminé"
|
msgstr "Document terminé"
|
||||||
|
|
||||||
@@ -711,7 +715,7 @@ msgid "Document created"
|
|||||||
msgstr "Document créé"
|
msgstr "Document créé"
|
||||||
|
|
||||||
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
#: packages/email/templates/document-created-from-direct-template.tsx:32
|
||||||
#: packages/lib/server-only/template/create-document-from-direct-template.ts:573
|
#: packages/lib/server-only/template/create-document-from-direct-template.ts:567
|
||||||
msgid "Document created from direct template"
|
msgid "Document created from direct template"
|
||||||
msgstr "Document créé à partir d'un modèle direct"
|
msgstr "Document créé à partir d'un modèle direct"
|
||||||
|
|
||||||
@@ -736,15 +740,15 @@ msgstr "Document Supprimé !"
|
|||||||
msgid "Document Distribution Method"
|
msgid "Document Distribution Method"
|
||||||
msgstr "Méthode de distribution du document"
|
msgstr "Méthode de distribution du document"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:326
|
#: packages/lib/utils/document-audit-logs.ts:330
|
||||||
msgid "Document external ID updated"
|
msgid "Document external ID updated"
|
||||||
msgstr "ID externe du document mis à jour"
|
msgstr "ID externe du document mis à jour"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:334
|
#: packages/lib/utils/document-audit-logs.ts:338
|
||||||
msgid "Document moved to team"
|
msgid "Document moved to team"
|
||||||
msgstr "Document déplacé vers l'équipe"
|
msgstr "Document déplacé vers l'équipe"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:318
|
#: packages/lib/utils/document-audit-logs.ts:322
|
||||||
msgid "Document opened"
|
msgid "Document opened"
|
||||||
msgstr "Document ouvert"
|
msgstr "Document ouvert"
|
||||||
|
|
||||||
@@ -759,23 +763,27 @@ msgstr "Document Rejeté"
|
|||||||
#~ msgid "Document Rejection Confirmed"
|
#~ msgid "Document Rejection Confirmed"
|
||||||
#~ msgstr "Document Rejection Confirmed"
|
#~ msgstr "Document Rejection Confirmed"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:330
|
#: packages/lib/utils/document-audit-logs.ts:294
|
||||||
|
msgid "Document restored"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: packages/lib/utils/document-audit-logs.ts:334
|
||||||
msgid "Document sent"
|
msgid "Document sent"
|
||||||
msgstr "Document envoyé"
|
msgstr "Document envoyé"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:310
|
#: packages/lib/utils/document-audit-logs.ts:314
|
||||||
msgid "Document signing auth updated"
|
msgid "Document signing auth updated"
|
||||||
msgstr "Authentification de signature de document mise à jour"
|
msgstr "Authentification de signature de document mise à jour"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:322
|
#: packages/lib/utils/document-audit-logs.ts:326
|
||||||
msgid "Document title updated"
|
msgid "Document title updated"
|
||||||
msgstr "Titre du document mis à jour"
|
msgstr "Titre du document mis à jour"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:314
|
#: packages/lib/utils/document-audit-logs.ts:318
|
||||||
msgid "Document updated"
|
msgid "Document updated"
|
||||||
msgstr "Document mis à jour"
|
msgstr "Document mis à jour"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:302
|
#: packages/lib/utils/document-audit-logs.ts:306
|
||||||
msgid "Document visibility updated"
|
msgid "Document visibility updated"
|
||||||
msgstr "Visibilité du document mise à jour"
|
msgstr "Visibilité du document mise à jour"
|
||||||
|
|
||||||
@@ -821,11 +829,11 @@ msgstr "L'email est requis"
|
|||||||
msgid "Email Options"
|
msgid "Email Options"
|
||||||
msgstr "Options d'email"
|
msgstr "Options d'email"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email resent"
|
msgid "Email resent"
|
||||||
msgstr "Email renvoyé"
|
msgstr "Email renvoyé"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:363
|
#: packages/lib/utils/document-audit-logs.ts:367
|
||||||
msgid "Email sent"
|
msgid "Email sent"
|
||||||
msgstr "Email envoyé"
|
msgstr "Email envoyé"
|
||||||
|
|
||||||
@@ -890,11 +898,11 @@ msgstr "Étiquette du champ"
|
|||||||
msgid "Field placeholder"
|
msgid "Field placeholder"
|
||||||
msgstr "Espace réservé du champ"
|
msgstr "Espace réservé du champ"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:294
|
#: packages/lib/utils/document-audit-logs.ts:298
|
||||||
msgid "Field signed"
|
msgid "Field signed"
|
||||||
msgstr "Champ signé"
|
msgstr "Champ signé"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:298
|
#: packages/lib/utils/document-audit-logs.ts:302
|
||||||
msgid "Field unsigned"
|
msgid "Field unsigned"
|
||||||
msgstr "Champ non signé"
|
msgstr "Champ non signé"
|
||||||
|
|
||||||
@@ -1199,8 +1207,8 @@ msgstr "Raison du rejet : {rejectionReason}"
|
|||||||
msgid "Receives copy"
|
msgid "Receives copy"
|
||||||
msgstr "Recevoir une copie"
|
msgstr "Recevoir une copie"
|
||||||
|
|
||||||
#: packages/lib/utils/document-audit-logs.ts:338
|
#: packages/lib/utils/document-audit-logs.ts:342
|
||||||
#: packages/lib/utils/document-audit-logs.ts:353
|
#: packages/lib/utils/document-audit-logs.ts:357
|
||||||
msgid "Recipient"
|
msgid "Recipient"
|
||||||
msgstr "Destinataire"
|
msgstr "Destinataire"
|
||||||
|
|
||||||
@@ -1774,7 +1782,7 @@ msgstr "Vous avez été invité à rejoindre {0} sur Documenso"
|
|||||||
msgid "You have been invited to join the following team"
|
msgid "You have been invited to join the following team"
|
||||||
msgstr "Vous avez été invité à rejoindre l'équipe suivante"
|
msgstr "Vous avez été invité à rejoindre l'équipe suivante"
|
||||||
|
|
||||||
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327
|
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:329
|
||||||
msgid "You have been removed from a document"
|
msgid "You have been removed from a document"
|
||||||
msgstr "Vous avez été supprimé d'un document"
|
msgstr "Vous avez été supprimé d'un document"
|
||||||
|
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ msgstr "Reconnaissance"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:127
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
|
||||||
@@ -413,7 +413,7 @@ msgstr "Tout"
|
|||||||
msgid "All documents"
|
msgid "All documents"
|
||||||
msgstr "Tous les documents"
|
msgstr "Tous les documents"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:40
|
||||||
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
msgid "All documents have been processed. Any new documents that are sent or received will show here."
|
||||||
msgstr "Tous les documents ont été traités. Tous nouveaux documents envoyés ou reçus s'afficheront ici."
|
msgstr "Tous les documents ont été traités. Tous nouveaux documents envoyés ou reçus s'afficheront ici."
|
||||||
|
|
||||||
@@ -516,7 +516,7 @@ msgstr "Une erreur est survenue lors de la désactivation de la signature par li
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:64
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:92
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:76
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:107
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:111
|
||||||
msgid "An error occurred while downloading your document."
|
msgid "An error occurred while downloading your document."
|
||||||
msgstr "Une erreur est survenue lors du téléchargement de votre document."
|
msgstr "Une erreur est survenue lors du téléchargement de votre document."
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ msgstr "Version de l'application"
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:146
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:150
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:142
|
||||||
msgid "Approve"
|
msgid "Approve"
|
||||||
msgstr "Approuver"
|
msgstr "Approuver"
|
||||||
@@ -784,6 +784,10 @@ msgstr "Détails de base"
|
|||||||
msgid "Billing"
|
msgid "Billing"
|
||||||
msgstr "Facturation"
|
msgstr "Facturation"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:51
|
||||||
|
msgid "Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/page.tsx:42
|
||||||
msgid "Branding Preferences"
|
msgid "Branding Preferences"
|
||||||
msgstr "Préférences de branding"
|
msgstr "Préférences de branding"
|
||||||
@@ -1283,7 +1287,6 @@ msgid "delete"
|
|||||||
msgstr "supprimer"
|
msgstr "supprimer"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:144
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:177
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:211
|
||||||
@@ -1361,6 +1364,7 @@ msgid "Delete your account and all its contents, including completed documents.
|
|||||||
msgstr "Supprimez votre compte et tout son contenu, y compris les documents complétés. Cette action est irréversible et annulera votre abonnement, alors procédez avec prudence."
|
msgstr "Supprimez votre compte et tout son contenu, y compris les documents complétés. Cette action est irréversible et annulera votre abonnement, alors procédez avec prudence."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:41
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:50
|
||||||
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:97
|
||||||
msgid "Deleted"
|
msgid "Deleted"
|
||||||
msgstr "Supprimé"
|
msgstr "Supprimé"
|
||||||
@@ -1477,6 +1481,10 @@ msgstr "Document Tout"
|
|||||||
msgid "Document Approved"
|
msgid "Document Approved"
|
||||||
msgstr "Document Approuvé"
|
msgstr "Document Approuvé"
|
||||||
|
|
||||||
|
#: apps/web/src/components/formatter/document-status.tsx:52
|
||||||
|
msgid "Document Bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:40
|
||||||
msgid "Document Cancelled"
|
msgid "Document Cancelled"
|
||||||
msgstr "Document Annulé"
|
msgstr "Document Annulé"
|
||||||
@@ -1611,7 +1619,7 @@ msgstr "Le document sera supprimé de manière permanente"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:108
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||||
#: apps/web/src/app/not-found.tsx:21
|
#: apps/web/src/app/not-found.tsx:21
|
||||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||||
@@ -1641,7 +1649,7 @@ msgstr "Vous n'avez pas de compte? <0>Inscrivez-vous</0>"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:123
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:162
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:166
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
|
||||||
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
|
||||||
@@ -1682,7 +1690,7 @@ msgid "Due to an unpaid invoice, your team has been restricted. Please settle th
|
|||||||
msgstr "En raison d'une facture impayée, votre équipe a été restreinte. Veuillez régler le paiement pour rétablir l'accès complet à votre équipe."
|
msgstr "En raison d'une facture impayée, votre équipe a été restreinte. Veuillez régler le paiement pour rétablir l'accès complet à votre équipe."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:136
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:167
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:171
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:85
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:118
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:74
|
||||||
@@ -1693,7 +1701,7 @@ msgstr "Dupliquer"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:104
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:115
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:102
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:156
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:111
|
||||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:65
|
||||||
@@ -2012,7 +2020,6 @@ msgstr "Voici comment cela fonctionne :"
|
|||||||
msgid "Hey I’m Timur"
|
msgid "Hey I’m Timur"
|
||||||
msgstr "Salut, je suis Timur"
|
msgstr "Salut, je suis Timur"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:189
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:202
|
||||||
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:155
|
||||||
msgid "Hide"
|
msgid "Hide"
|
||||||
@@ -2063,7 +2070,7 @@ msgstr "Documents de la boîte de réception"
|
|||||||
msgid "Include the Signing Certificate in the Document"
|
msgid "Include the Signing Certificate in the Document"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:53
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:50
|
||||||
msgid "Information"
|
msgid "Information"
|
||||||
msgstr "Information"
|
msgstr "Information"
|
||||||
@@ -2396,7 +2403,7 @@ msgstr "Déplacer le document vers l'équipe"
|
|||||||
msgid "Move Template to Team"
|
msgid "Move Template to Team"
|
||||||
msgstr "Déplacer le modèle vers l'équipe"
|
msgstr "Déplacer le modèle vers l'équipe"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:174
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:178
|
||||||
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
#: apps/web/src/app/(dashboard)/templates/data-table-action-dropdown.tsx:85
|
||||||
msgid "Move to Team"
|
msgid "Move to Team"
|
||||||
msgstr "Déplacer vers l'équipe"
|
msgstr "Déplacer vers l'équipe"
|
||||||
@@ -2460,6 +2467,10 @@ msgstr "Champ suivant"
|
|||||||
msgid "No active drafts"
|
msgid "No active drafts"
|
||||||
msgstr "Pas de brouillons actifs"
|
msgstr "Pas de brouillons actifs"
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
||||||
|
msgid "No documents in the bin"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
#: apps/web/src/app/(signing)/sign/[token]/rejected/page.tsx:99
|
||||||
msgid "No further action is required from you at this time."
|
msgid "No further action is required from you at this time."
|
||||||
msgstr "Aucune autre action n'est requise de votre part pour le moment."
|
msgstr "Aucune autre action n'est requise de votre part pour le moment."
|
||||||
@@ -2516,7 +2527,7 @@ msgid "Not supported"
|
|||||||
msgstr "Non pris en charge"
|
msgstr "Non pris en charge"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:19
|
||||||
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:34
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:39
|
||||||
msgid "Nothing to do"
|
msgid "Nothing to do"
|
||||||
msgstr "Rien à faire"
|
msgstr "Rien à faire"
|
||||||
|
|
||||||
@@ -3206,12 +3217,12 @@ msgid "Setup"
|
|||||||
msgstr "Configuration"
|
msgstr "Configuration"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:148
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:193
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:207
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr "Partager"
|
msgstr "Partager"
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:179
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:219
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:233
|
||||||
msgid "Share Signing Card"
|
msgid "Share Signing Card"
|
||||||
msgstr "Partager la carte de signature"
|
msgstr "Partager la carte de signature"
|
||||||
|
|
||||||
@@ -3233,7 +3244,7 @@ msgstr "Afficher des modèles dans le profil public de votre équipe pour que vo
|
|||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:83
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:139
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:143
|
||||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
|
||||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||||
@@ -3357,7 +3368,7 @@ msgid "Signing in..."
|
|||||||
msgstr "Connexion en cours..."
|
msgstr "Connexion en cours..."
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:160
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:203
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:217
|
||||||
msgid "Signing Links"
|
msgid "Signing Links"
|
||||||
msgstr "Liens de signature"
|
msgstr "Liens de signature"
|
||||||
|
|
||||||
@@ -3388,7 +3399,7 @@ msgstr "Paramètres du site"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-audit-log-button.tsx:65
|
||||||
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
#: apps/web/src/app/(dashboard)/documents/[id]/logs/download-certificate-button.tsx:68
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:75
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:106
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:110
|
||||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:82
|
||||||
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
|
||||||
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
|
||||||
@@ -3873,6 +3884,10 @@ msgstr "Il n'y a pas de brouillons actifs pour le moment. Vous pouvez téléchar
|
|||||||
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
msgid "There are no completed documents yet. Documents that you have created or received will appear here once completed."
|
||||||
msgstr "Il n'y a pas encore de documents complétés. Les documents que vous avez créés ou reçus apparaîtront ici une fois complétés."
|
msgstr "Il n'y a pas encore de documents complétés. Les documents que vous avez créés ou reçus apparaîtront ici une fois complétés."
|
||||||
|
|
||||||
|
#: apps/web/src/app/(dashboard)/documents/empty-state.tsx:35
|
||||||
|
msgid "There are no documents in the bin."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:70
|
||||||
msgid "They have permission on your behalf to:"
|
msgid "They have permission on your behalf to:"
|
||||||
msgstr "Ils ont la permission en votre nom de:"
|
msgstr "Ils ont la permission en votre nom de:"
|
||||||
@@ -4432,7 +4447,7 @@ msgstr "Historique des versions"
|
|||||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:95
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
|
||||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:132
|
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:136
|
||||||
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
|
||||||
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
|
||||||
msgid "View"
|
msgid "View"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export const ZDocumentAuditLogTypeSchema = z.enum([
|
|||||||
'DOCUMENT_COMPLETED', // When the document is sealed and fully completed.
|
'DOCUMENT_COMPLETED', // When the document is sealed and fully completed.
|
||||||
'DOCUMENT_CREATED', // When the document is created.
|
'DOCUMENT_CREATED', // When the document is created.
|
||||||
'DOCUMENT_DELETED', // When the document is soft deleted.
|
'DOCUMENT_DELETED', // When the document is soft deleted.
|
||||||
|
'DOCUMENT_RESTORED', // When the document is restored.
|
||||||
'DOCUMENT_FIELD_INSERTED', // When a field is inserted (signed/approved/etc) by a recipient.
|
'DOCUMENT_FIELD_INSERTED', // When a field is inserted (signed/approved/etc) by a recipient.
|
||||||
'DOCUMENT_FIELD_UNINSERTED', // When a field is uninserted by a recipient.
|
'DOCUMENT_FIELD_UNINSERTED', // When a field is uninserted by a recipient.
|
||||||
'DOCUMENT_VISIBILITY_UPDATED', // When the document visibility scope is updated
|
'DOCUMENT_VISIBILITY_UPDATED', // When the document visibility scope is updated
|
||||||
@@ -225,6 +226,16 @@ export const ZDocumentAuditLogEventDocumentDeletedSchema = z.object({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Document restored.
|
||||||
|
*/
|
||||||
|
export const ZDocumentAuditLogEventDocumentRestoredSchema = z.object({
|
||||||
|
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED),
|
||||||
|
data: z.object({
|
||||||
|
type: z.enum(['RESTORE']),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event: Document field inserted.
|
* Event: Document field inserted.
|
||||||
*/
|
*/
|
||||||
@@ -490,6 +501,7 @@ export const ZDocumentAuditLogSchema = ZDocumentAuditLogBaseSchema.and(
|
|||||||
ZDocumentAuditLogEventDocumentCreatedSchema,
|
ZDocumentAuditLogEventDocumentCreatedSchema,
|
||||||
ZDocumentAuditLogEventDocumentDeletedSchema,
|
ZDocumentAuditLogEventDocumentDeletedSchema,
|
||||||
ZDocumentAuditLogEventDocumentMovedToTeamSchema,
|
ZDocumentAuditLogEventDocumentMovedToTeamSchema,
|
||||||
|
ZDocumentAuditLogEventDocumentRestoredSchema,
|
||||||
ZDocumentAuditLogEventDocumentFieldInsertedSchema,
|
ZDocumentAuditLogEventDocumentFieldInsertedSchema,
|
||||||
ZDocumentAuditLogEventDocumentFieldUninsertedSchema,
|
ZDocumentAuditLogEventDocumentFieldUninsertedSchema,
|
||||||
ZDocumentAuditLogEventDocumentVisibilitySchema,
|
ZDocumentAuditLogEventDocumentVisibilitySchema,
|
||||||
|
|||||||
@@ -290,6 +290,10 @@ export const formatDocumentAuditLogAction = (
|
|||||||
anonymous: msg`Document deleted`,
|
anonymous: msg`Document deleted`,
|
||||||
identified: msg`${prefix} deleted the document`,
|
identified: msg`${prefix} deleted the document`,
|
||||||
}))
|
}))
|
||||||
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED }, () => ({
|
||||||
|
anonymous: msg`Document restored`,
|
||||||
|
identified: msg`${prefix} restored the document`,
|
||||||
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
|
||||||
anonymous: msg`Field signed`,
|
anonymous: msg`Field signed`,
|
||||||
identified: msg`${prefix} signed a field`,
|
identified: msg`${prefix} signed a field`,
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
import Honeybadger from '@honeybadger-io/js';
|
|
||||||
|
|
||||||
export const buildLogger = () => {
|
|
||||||
if (process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY) {
|
|
||||||
return new HoneybadgerLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DefaultLogger();
|
|
||||||
};
|
|
||||||
|
|
||||||
interface LoggerDescriptionOptions {
|
|
||||||
method?: string;
|
|
||||||
path?: string;
|
|
||||||
context?: Record<string, unknown>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of log to be captured.
|
|
||||||
*
|
|
||||||
* Defaults to `info`.
|
|
||||||
*/
|
|
||||||
level?: 'info' | 'error' | 'critical';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic logger implementation intended to be used in the server side for capturing
|
|
||||||
* explicit errors and other logs.
|
|
||||||
*
|
|
||||||
* Not intended to capture the request and responses.
|
|
||||||
*/
|
|
||||||
interface Logger {
|
|
||||||
log(message: string, options?: LoggerDescriptionOptions): void;
|
|
||||||
|
|
||||||
error(error: Error, options?: LoggerDescriptionOptions): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultLogger implements Logger {
|
|
||||||
log(_message: string, _options?: LoggerDescriptionOptions) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
error(_error: Error, _options?: LoggerDescriptionOptions): void {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HoneybadgerLogger implements Logger {
|
|
||||||
constructor() {
|
|
||||||
if (!process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY) {
|
|
||||||
throw new Error('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY is not set');
|
|
||||||
}
|
|
||||||
|
|
||||||
Honeybadger.configure({
|
|
||||||
apiKey: process.env.NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Honeybadger doesn't really have a non-error logging system.
|
|
||||||
*/
|
|
||||||
log(message: string, options?: LoggerDescriptionOptions) {
|
|
||||||
const { context = {}, level = 'info' } = options || {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
Honeybadger.event({
|
|
||||||
message,
|
|
||||||
context: {
|
|
||||||
level,
|
|
||||||
...context,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error(error: Error, options?: LoggerDescriptionOptions): void {
|
|
||||||
const { context = {}, level = 'error', method, path } = options || {};
|
|
||||||
|
|
||||||
const tags = [`level:${level}`];
|
|
||||||
let errorMessage = error.message;
|
|
||||||
|
|
||||||
if (method) {
|
|
||||||
tags.push(`method:${method}`);
|
|
||||||
|
|
||||||
errorMessage = `[${method}]: ${error.message}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
tags.push(`path:${path}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Honeybadger.notify(errorMessage, {
|
|
||||||
context: {
|
|
||||||
level,
|
|
||||||
...context,
|
|
||||||
},
|
|
||||||
tags,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ export const ExtendedDocumentStatus = {
|
|||||||
...DocumentStatus,
|
...DocumentStatus,
|
||||||
INBOX: 'INBOX',
|
INBOX: 'INBOX',
|
||||||
ALL: 'ALL',
|
ALL: 'ALL',
|
||||||
|
BIN: 'BIN',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type ExtendedDocumentStatus =
|
export type ExtendedDocumentStatus =
|
||||||
|
|||||||
@@ -44,9 +44,10 @@ export const authRouter = router({
|
|||||||
const { name, email, password, signature, url } = input;
|
const { name, email, password, signature, url } = input;
|
||||||
|
|
||||||
if (IS_BILLING_ENABLED() && url && url.length < 6) {
|
if (IS_BILLING_ENABLED() && url && url.length < 6) {
|
||||||
throw new AppError(AppErrorCode.PREMIUM_PROFILE_URL, {
|
throw new AppError(
|
||||||
message: 'Only subscribers can have a username shorter than 6 characters',
|
AppErrorCode.PREMIUM_PROFILE_URL,
|
||||||
});
|
'Only subscribers can have a username shorter than 6 characters',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await createUser({ name, email, password, signature, url });
|
const user = await createUser({ name, email, password, signature, url });
|
||||||
@@ -65,7 +66,7 @@ export const authRouter = router({
|
|||||||
const error = AppError.parseError(err);
|
const error = AppError.parseError(err);
|
||||||
|
|
||||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||||
throw error;
|
throw AppError.parseErrorToTRPCError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let message =
|
let message =
|
||||||
@@ -117,7 +118,7 @@ export const authRouter = router({
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
throw err;
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document
|
|||||||
import { getDocumentWithDetailsById } from '@documenso/lib/server-only/document/get-document-with-details-by-id';
|
import { getDocumentWithDetailsById } from '@documenso/lib/server-only/document/get-document-with-details-by-id';
|
||||||
import { moveDocumentToTeam } from '@documenso/lib/server-only/document/move-document-to-team';
|
import { moveDocumentToTeam } from '@documenso/lib/server-only/document/move-document-to-team';
|
||||||
import { resendDocument } from '@documenso/lib/server-only/document/resend-document';
|
import { resendDocument } from '@documenso/lib/server-only/document/resend-document';
|
||||||
|
import { restoreDocument } from '@documenso/lib/server-only/document/restore-document';
|
||||||
import { searchDocumentsWithKeyword } from '@documenso/lib/server-only/document/search-documents-with-keyword';
|
import { searchDocumentsWithKeyword } from '@documenso/lib/server-only/document/search-documents-with-keyword';
|
||||||
import { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
import { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
||||||
import { updateDocumentSettings } from '@documenso/lib/server-only/document/update-document-settings';
|
import { updateDocumentSettings } from '@documenso/lib/server-only/document/update-document-settings';
|
||||||
@@ -38,6 +39,7 @@ import {
|
|||||||
ZGetDocumentWithDetailsByIdQuerySchema,
|
ZGetDocumentWithDetailsByIdQuerySchema,
|
||||||
ZMoveDocumentsToTeamSchema,
|
ZMoveDocumentsToTeamSchema,
|
||||||
ZResendDocumentMutationSchema,
|
ZResendDocumentMutationSchema,
|
||||||
|
ZRestoreDocumentMutationSchema,
|
||||||
ZSearchDocumentsMutationSchema,
|
ZSearchDocumentsMutationSchema,
|
||||||
ZSendDocumentMutationSchema,
|
ZSendDocumentMutationSchema,
|
||||||
ZSetPasswordForDocumentMutationSchema,
|
ZSetPasswordForDocumentMutationSchema,
|
||||||
@@ -223,6 +225,32 @@ export const documentRouter = router({
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
restoreDocument: authenticatedProcedure
|
||||||
|
.input(ZRestoreDocumentMutationSchema)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
|
const { id, teamId } = input;
|
||||||
|
|
||||||
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
const restoredDocument = await restoreDocument({
|
||||||
|
id,
|
||||||
|
userId,
|
||||||
|
teamId,
|
||||||
|
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||||
|
});
|
||||||
|
|
||||||
|
return restoredDocument;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw new TRPCError({
|
||||||
|
code: 'BAD_REQUEST',
|
||||||
|
message: 'We were unable to restore this document. Please try again later.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
findDocumentAuditLogs: authenticatedProcedure
|
findDocumentAuditLogs: authenticatedProcedure
|
||||||
.input(ZFindDocumentAuditLogsQuerySchema)
|
.input(ZFindDocumentAuditLogsQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
|||||||
@@ -211,6 +211,11 @@ export const ZDeleteDraftDocumentMutationSchema = z.object({
|
|||||||
teamId: z.number().min(1).optional(),
|
teamId: z.number().min(1).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ZRestoreDocumentMutationSchema = z.object({
|
||||||
|
id: z.number().min(1),
|
||||||
|
teamId: z.number().min(1).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
export type TDeleteDraftDocumentMutationSchema = z.infer<typeof ZDeleteDraftDocumentMutationSchema>;
|
export type TDeleteDraftDocumentMutationSchema = z.infer<typeof ZDeleteDraftDocumentMutationSchema>;
|
||||||
|
|
||||||
export const ZSearchDocumentsMutationSchema = z.object({
|
export const ZSearchDocumentsMutationSchema = z.object({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { TRPCError } from '@trpc/server';
|
import { TRPCError } from '@trpc/server';
|
||||||
|
|
||||||
|
import { AppError } from '@documenso/lib/errors/app-error';
|
||||||
import { getFieldById } from '@documenso/lib/server-only/field/get-field-by-id';
|
import { getFieldById } from '@documenso/lib/server-only/field/get-field-by-id';
|
||||||
import { removeSignedFieldWithToken } from '@documenso/lib/server-only/field/remove-signed-field-with-token';
|
import { removeSignedFieldWithToken } from '@documenso/lib/server-only/field/remove-signed-field-with-token';
|
||||||
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
||||||
@@ -95,7 +96,7 @@ export const fieldRouter = router({
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
throw err;
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -100,9 +100,10 @@ export const profileRouter = router({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (subscriptions.length === 0) {
|
if (subscriptions.length === 0) {
|
||||||
throw new AppError(AppErrorCode.PREMIUM_PROFILE_URL, {
|
throw new AppError(
|
||||||
message: 'Only subscribers can have a username shorter than 6 characters',
|
AppErrorCode.PREMIUM_PROFILE_URL,
|
||||||
});
|
'Only subscribers can have a username shorter than 6 characters',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ export const profileRouter = router({
|
|||||||
const error = AppError.parseError(err);
|
const error = AppError.parseError(err);
|
||||||
|
|
||||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||||
throw error;
|
throw AppError.parseErrorToTRPCError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
|
|||||||
@@ -76,42 +76,67 @@ export const teamRouter = router({
|
|||||||
acceptTeamInvitation: authenticatedProcedure
|
acceptTeamInvitation: authenticatedProcedure
|
||||||
.input(ZAcceptTeamInvitationMutationSchema)
|
.input(ZAcceptTeamInvitationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await acceptTeamInvitation({
|
return await acceptTeamInvitation({
|
||||||
teamId: input.teamId,
|
teamId: input.teamId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
declineTeamInvitation: authenticatedProcedure
|
declineTeamInvitation: authenticatedProcedure
|
||||||
.input(ZDeclineTeamInvitationMutationSchema)
|
.input(ZDeclineTeamInvitationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await declineTeamInvitation({
|
return await declineTeamInvitation({
|
||||||
teamId: input.teamId,
|
teamId: input.teamId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createBillingPortal: authenticatedProcedure
|
createBillingPortal: authenticatedProcedure
|
||||||
.input(ZCreateTeamBillingPortalMutationSchema)
|
.input(ZCreateTeamBillingPortalMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await createTeamBillingPortal({
|
return await createTeamBillingPortal({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createTeam: authenticatedProcedure
|
createTeam: authenticatedProcedure
|
||||||
.input(ZCreateTeamMutationSchema)
|
.input(ZCreateTeamMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await createTeam({
|
return await createTeam({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createTeamEmailVerification: authenticatedProcedure
|
createTeamEmailVerification: authenticatedProcedure
|
||||||
.input(ZCreateTeamEmailVerificationMutationSchema)
|
.input(ZCreateTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await createTeamEmailVerification({
|
return await createTeamEmailVerification({
|
||||||
teamId: input.teamId,
|
teamId: input.teamId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@@ -120,194 +145,343 @@ export const teamRouter = router({
|
|||||||
name: input.name,
|
name: input.name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createTeamMemberInvites: authenticatedProcedure
|
createTeamMemberInvites: authenticatedProcedure
|
||||||
.input(ZCreateTeamMemberInvitesMutationSchema)
|
.input(ZCreateTeamMemberInvitesMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await createTeamMemberInvites({
|
return await createTeamMemberInvites({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
userName: ctx.user.name ?? '',
|
userName: ctx.user.name ?? '',
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createTeamPendingCheckout: authenticatedProcedure
|
createTeamPendingCheckout: authenticatedProcedure
|
||||||
.input(ZCreateTeamPendingCheckoutMutationSchema)
|
.input(ZCreateTeamPendingCheckoutMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await createTeamPendingCheckoutSession({
|
return await createTeamPendingCheckoutSession({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeam: authenticatedProcedure
|
deleteTeam: authenticatedProcedure
|
||||||
.input(ZDeleteTeamMutationSchema)
|
.input(ZDeleteTeamMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeam({
|
return await deleteTeam({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamEmail: authenticatedProcedure
|
deleteTeamEmail: authenticatedProcedure
|
||||||
.input(ZDeleteTeamEmailMutationSchema)
|
.input(ZDeleteTeamEmailMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamEmail({
|
return await deleteTeamEmail({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
userEmail: ctx.user.email,
|
userEmail: ctx.user.email,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamEmailVerification: authenticatedProcedure
|
deleteTeamEmailVerification: authenticatedProcedure
|
||||||
.input(ZDeleteTeamEmailVerificationMutationSchema)
|
.input(ZDeleteTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamEmailVerification({
|
return await deleteTeamEmailVerification({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamMemberInvitations: authenticatedProcedure
|
deleteTeamMemberInvitations: authenticatedProcedure
|
||||||
.input(ZDeleteTeamMemberInvitationsMutationSchema)
|
.input(ZDeleteTeamMemberInvitationsMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamMemberInvitations({
|
return await deleteTeamMemberInvitations({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamMembers: authenticatedProcedure
|
deleteTeamMembers: authenticatedProcedure
|
||||||
.input(ZDeleteTeamMembersMutationSchema)
|
.input(ZDeleteTeamMembersMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamMembers({
|
return await deleteTeamMembers({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamPending: authenticatedProcedure
|
deleteTeamPending: authenticatedProcedure
|
||||||
.input(ZDeleteTeamPendingMutationSchema)
|
.input(ZDeleteTeamPendingMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamPending({
|
return await deleteTeamPending({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTeamTransferRequest: authenticatedProcedure
|
deleteTeamTransferRequest: authenticatedProcedure
|
||||||
.input(ZDeleteTeamTransferRequestMutationSchema)
|
.input(ZDeleteTeamTransferRequestMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await deleteTeamTransferRequest({
|
return await deleteTeamTransferRequest({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
findTeamInvoices: authenticatedProcedure
|
findTeamInvoices: authenticatedProcedure
|
||||||
.input(ZFindTeamInvoicesQuerySchema)
|
.input(ZFindTeamInvoicesQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await findTeamInvoices({
|
return await findTeamInvoices({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
findTeamMemberInvites: authenticatedProcedure
|
findTeamMemberInvites: authenticatedProcedure
|
||||||
.input(ZFindTeamMemberInvitesQuerySchema)
|
.input(ZFindTeamMemberInvitesQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await findTeamMemberInvites({
|
return await findTeamMemberInvites({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
findTeamMembers: authenticatedProcedure
|
findTeamMembers: authenticatedProcedure
|
||||||
.input(ZFindTeamMembersQuerySchema)
|
.input(ZFindTeamMembersQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await findTeamMembers({
|
return await findTeamMembers({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
findTeams: authenticatedProcedure.input(ZFindTeamsQuerySchema).query(async ({ input, ctx }) => {
|
findTeams: authenticatedProcedure.input(ZFindTeamsQuerySchema).query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await findTeams({
|
return await findTeams({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
findTeamsPending: authenticatedProcedure
|
findTeamsPending: authenticatedProcedure
|
||||||
.input(ZFindTeamsPendingQuerySchema)
|
.input(ZFindTeamsPendingQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await findTeamsPending({
|
return await findTeamsPending({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeam: authenticatedProcedure.input(ZGetTeamQuerySchema).query(async ({ input, ctx }) => {
|
getTeam: authenticatedProcedure.input(ZGetTeamQuerySchema).query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await getTeamById({ teamId: input.teamId, userId: ctx.user.id });
|
return await getTeamById({ teamId: input.teamId, userId: ctx.user.id });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeamEmailByEmail: authenticatedProcedure.query(async ({ ctx }) => {
|
getTeamEmailByEmail: authenticatedProcedure.query(async ({ ctx }) => {
|
||||||
|
try {
|
||||||
return await getTeamEmailByEmail({ email: ctx.user.email });
|
return await getTeamEmailByEmail({ email: ctx.user.email });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeamInvitations: authenticatedProcedure.query(async ({ ctx }) => {
|
getTeamInvitations: authenticatedProcedure.query(async ({ ctx }) => {
|
||||||
|
try {
|
||||||
return await getTeamInvitations({ email: ctx.user.email });
|
return await getTeamInvitations({ email: ctx.user.email });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeamMembers: authenticatedProcedure
|
getTeamMembers: authenticatedProcedure
|
||||||
.input(ZGetTeamMembersQuerySchema)
|
.input(ZGetTeamMembersQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await getTeamMembers({ teamId: input.teamId, userId: ctx.user.id });
|
return await getTeamMembers({ teamId: input.teamId, userId: ctx.user.id });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeamPrices: authenticatedProcedure.query(async () => {
|
getTeamPrices: authenticatedProcedure.query(async () => {
|
||||||
|
try {
|
||||||
return await getTeamPrices();
|
return await getTeamPrices();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTeams: authenticatedProcedure.query(async ({ ctx }) => {
|
getTeams: authenticatedProcedure.query(async ({ ctx }) => {
|
||||||
|
try {
|
||||||
return await getTeams({ userId: ctx.user.id });
|
return await getTeams({ userId: ctx.user.id });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
leaveTeam: authenticatedProcedure
|
leaveTeam: authenticatedProcedure
|
||||||
.input(ZLeaveTeamMutationSchema)
|
.input(ZLeaveTeamMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await leaveTeam({
|
return await leaveTeam({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeam: authenticatedProcedure
|
updateTeam: authenticatedProcedure
|
||||||
.input(ZUpdateTeamMutationSchema)
|
.input(ZUpdateTeamMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await updateTeam({
|
return await updateTeam({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeamEmail: authenticatedProcedure
|
updateTeamEmail: authenticatedProcedure
|
||||||
.input(ZUpdateTeamEmailMutationSchema)
|
.input(ZUpdateTeamEmailMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await updateTeamEmail({
|
return await updateTeamEmail({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeamMember: authenticatedProcedure
|
updateTeamMember: authenticatedProcedure
|
||||||
.input(ZUpdateTeamMemberMutationSchema)
|
.input(ZUpdateTeamMemberMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await updateTeamMember({
|
return await updateTeamMember({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeamPublicProfile: authenticatedProcedure
|
updateTeamPublicProfile: authenticatedProcedure
|
||||||
@@ -332,7 +506,7 @@ export const teamRouter = router({
|
|||||||
const error = AppError.parseError(err);
|
const error = AppError.parseError(err);
|
||||||
|
|
||||||
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
|
||||||
throw error;
|
throw AppError.parseErrorToTRPCError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -346,30 +520,48 @@ export const teamRouter = router({
|
|||||||
requestTeamOwnershipTransfer: authenticatedProcedure
|
requestTeamOwnershipTransfer: authenticatedProcedure
|
||||||
.input(ZRequestTeamOwnerhsipTransferMutationSchema)
|
.input(ZRequestTeamOwnerhsipTransferMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
return await requestTeamOwnershipTransfer({
|
return await requestTeamOwnershipTransfer({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
userName: ctx.user.name ?? '',
|
userName: ctx.user.name ?? '',
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
resendTeamEmailVerification: authenticatedProcedure
|
resendTeamEmailVerification: authenticatedProcedure
|
||||||
.input(ZResendTeamEmailVerificationMutationSchema)
|
.input(ZResendTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
await resendTeamEmailVerification({
|
await resendTeamEmailVerification({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
resendTeamMemberInvitation: authenticatedProcedure
|
resendTeamMemberInvitation: authenticatedProcedure
|
||||||
.input(ZResendTeamMemberInvitationMutationSchema)
|
.input(ZResendTeamMemberInvitationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
try {
|
||||||
await resendTeamMemberInvitation({
|
await resendTeamMemberInvitation({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
userName: ctx.user.name ?? '',
|
userName: ctx.user.name ?? '',
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeamBrandingSettings: authenticatedProcedure
|
updateTeamBrandingSettings: authenticatedProcedure
|
||||||
@@ -377,11 +569,17 @@ export const teamRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { teamId, settings } = input;
|
const { teamId, settings } = input;
|
||||||
|
|
||||||
|
try {
|
||||||
return await updateTeamBrandingSettings({
|
return await updateTeamBrandingSettings({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
settings,
|
settings,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateTeamDocumentSettings: authenticatedProcedure
|
updateTeamDocumentSettings: authenticatedProcedure
|
||||||
@@ -389,10 +587,16 @@ export const teamRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { teamId, settings } = input;
|
const { teamId, settings } = input;
|
||||||
|
|
||||||
|
try {
|
||||||
return await updateTeamDocumentSettings({
|
return await updateTeamDocumentSettings({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
settings,
|
settings,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
throw AppError.parseErrorToTRPCError(err);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user