mirror of
https://github.com/documenso/documenso
synced 2026-04-21 13:27:18 +00:00
Merge branch 'main' into fix/replace-linter-with-biome
This commit is contained in:
commit
126fb5fba5
149 changed files with 9015 additions and 1008 deletions
239
.agents/plans/bright-emerald-flower-bullmq-background-jobs.md
Normal file
239
.agents/plans/bright-emerald-flower-bullmq-background-jobs.md
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
---
|
||||
date: 2026-03-26
|
||||
title: Bullmq Background Jobs
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
The codebase has a well-designed background job provider abstraction (`BaseJobProvider`) with two existing implementations:
|
||||
|
||||
- **InngestJobProvider** — cloud/SaaS provider, externally hosted
|
||||
- **LocalJobProvider** — database-backed (Postgres via Prisma), uses HTTP self-calls to dispatch
|
||||
|
||||
The goal is to add a third provider backed by a proper job queue library for self-hosted deployments that need more reliability than the Local provider offers.
|
||||
|
||||
### Current Architecture
|
||||
|
||||
All code lives in `packages/lib/jobs/`:
|
||||
|
||||
- `client/base.ts` — Abstract `BaseJobProvider` with 4 methods: `defineJob()`, `triggerJob()`, `getApiHandler()`, `startCron()`
|
||||
- `client/client.ts` — `JobClient` facade, selects provider via `NEXT_PRIVATE_JOBS_PROVIDER` env var
|
||||
- `client/inngest.ts` — Inngest implementation
|
||||
- `client/local.ts` — Local/Postgres implementation
|
||||
- `client/_internal/job.ts` — Core types: `JobDefinition`, `JobRunIO`, `SimpleTriggerJobOptions`
|
||||
- `definitions/` — 19 job definitions (15 event-triggered, 4 cron)
|
||||
|
||||
The `JobRunIO` interface provided to handlers includes:
|
||||
|
||||
- `runTask(cacheKey, callback)` — idempotent task execution (cached via `BackgroundJobTask` table)
|
||||
- `triggerJob(cacheKey, options)` — chain jobs from within handlers
|
||||
- `wait(cacheKey, ms)` — delay/sleep (not implemented in Local provider)
|
||||
- `logger` — structured logging
|
||||
|
||||
### Local Provider Limitations
|
||||
|
||||
The current Local provider has several issues that motivate this work:
|
||||
|
||||
1. `io.wait()` throws "Not implemented"
|
||||
2. HTTP self-call with 150ms fire-and-forget `Promise.race` is fragile
|
||||
3. No concurrency control — jobs run in the web server process
|
||||
4. No real retry backoff (immediate re-dispatch)
|
||||
5. No monitoring/visibility into job status
|
||||
6. Jobs compete for resources with HTTP request handling
|
||||
|
||||
---
|
||||
|
||||
## Provider Evaluation
|
||||
|
||||
Three alternatives were evaluated against the existing provider interface and project requirements.
|
||||
|
||||
### BullMQ (Redis-backed) — Recommended
|
||||
|
||||
| Attribute | Detail |
|
||||
| ------------------- | -------------------------- |
|
||||
| Backend | Redis 7.x |
|
||||
| npm downloads/month | ~15M |
|
||||
| TypeScript | Native |
|
||||
| Delayed jobs | Yes (ms precision) |
|
||||
| Cron/repeatable | Yes (`upsertJobScheduler`) |
|
||||
| Retries + backoff | Yes (exponential, custom) |
|
||||
| Concurrency control | Yes (per-worker) |
|
||||
| Rate limiting | Yes (per-queue, per-group) |
|
||||
| Dashboard | Bull Board (mature) |
|
||||
| New infrastructure | Yes — Redis required |
|
||||
|
||||
**Why BullMQ**: Most mature and widely-adopted Node.js queue. Native delayed jobs solve the `io.wait()` gap. Redis is purpose-built for queue workloads and keeps Postgres clean for application data. Bull Board gives immediate operational visibility. The provider abstraction already exists so wrapping BullMQ is straightforward.
|
||||
|
||||
**Trade-off**: Requires Redis, which is additional infrastructure. However, Redis is a single Docker Compose service or a free Upstash tier, and the operational benefit is significant.
|
||||
|
||||
### pg-boss (PostgreSQL-backed) — Strong Alternative
|
||||
|
||||
| Attribute | Detail |
|
||||
| ------------------- | ----------------------------- |
|
||||
| Backend | PostgreSQL (existing) |
|
||||
| npm downloads/month | ~1.4M |
|
||||
| TypeScript | Native |
|
||||
| Delayed jobs | Yes (`startAfter`) |
|
||||
| Cron/repeatable | Yes (`schedule()`) |
|
||||
| New infrastructure | No — reuses existing Postgres |
|
||||
|
||||
**Why it could work**: Zero new infrastructure since the project already uses Postgres. API maps well to existing patterns.
|
||||
|
||||
**Why it's second choice**: Polling-based (no LISTEN/NOTIFY), adds write amplification to the primary database, smaller ecosystem, no dashboard. At scale, queue operations on the primary database become a concern.
|
||||
|
||||
### Graphile Worker (PostgreSQL-backed) — Less Suitable
|
||||
|
||||
Uses LISTEN/NOTIFY for instant pickup but has a file-based task convention and separate schema that don't mesh well with the existing Prisma-centric architecture. Would require more adapter work.
|
||||
|
||||
### Improving the Local Provider — Not Recommended
|
||||
|
||||
Fixing the Local provider's issues (wait support, replacing HTTP self-calls, adding concurrency control, backoff) essentially means rebuilding a queue library from scratch with less robustness and no community maintenance.
|
||||
|
||||
---
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Proceed with BullMQ.** It's the most capable option, maps cleanly to the existing provider interface, and is the standard choice for production Node.js applications. Redis is lightweight infrastructure with managed options available at every cloud provider.
|
||||
|
||||
**If Redis is a hard blocker**, pg-boss is the clear fallback — but the plan below assumes BullMQ.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: BullMQ Provider Core
|
||||
|
||||
**File: `packages/lib/jobs/client/bullmq.ts`**
|
||||
|
||||
Create `BullMQJobProvider extends BaseJobProvider` with singleton pattern matching the existing providers.
|
||||
|
||||
Key implementation details:
|
||||
|
||||
1. **Constructor / `getInstance()`**
|
||||
- Initialize a Redis `IORedis` connection using new env var: `NEXT_PRIVATE_REDIS_URL`
|
||||
- Create a single `Queue` instance for dispatching jobs, using `NEXT_PRIVATE_REDIS_PREFIX` as the BullMQ `prefix` option (defaults to `documenso` if unset). This namespaces all Redis keys so multiple environments (worktrees, branches, developers) sharing the same Redis instance don't collide.
|
||||
- Create a single `Worker` instance for processing jobs (in-process, same prefix)
|
||||
- Store job definitions in a `_jobDefinitions` record (same pattern as Local provider)
|
||||
|
||||
2. **`defineJob()`**
|
||||
- Store definition in `_jobDefinitions` keyed by ID
|
||||
- If the definition has a `trigger.cron`, register it via `queue.upsertJobScheduler()` with the cron expression
|
||||
|
||||
3. **`triggerJob(options)`**
|
||||
- Find eligible definitions by `trigger.name` (same lookup as Local provider)
|
||||
- For each, call `queue.add(jobDefinitionId, payload)` with appropriate options
|
||||
- Support `options.id` for deduplication via BullMQ's `jobId` option
|
||||
|
||||
4. **`getApiHandler()`**
|
||||
- Return a minimal health-check / queue-status handler. Unlike the Local provider, BullMQ workers don't need an HTTP endpoint to receive jobs — they pull from Redis directly. The API handler can return queue metrics for monitoring.
|
||||
|
||||
5. **`startCron()`**
|
||||
- No-op — cron is handled by BullMQ's `upsertJobScheduler` registered during `defineJob()`
|
||||
|
||||
6. **Worker setup**
|
||||
- Single worker processes all job types by dispatching to the correct handler from `_jobDefinitions`
|
||||
- Configure concurrency with a default of 10 (overridable via `NEXT_PRIVATE_BULLMQ_CONCURRENCY` env var for those who need to tune it)
|
||||
- Configure retry with exponential backoff: `backoff: { type: 'exponential', delay: 1000 }`
|
||||
- Default 3 retries (matching current Local provider behavior)
|
||||
|
||||
7. **`createJobRunIO(jobId)`** — Implement `JobRunIO`:
|
||||
- `runTask()`: Reuse the existing `BackgroundJobTask` Prisma table for idempotent task tracking (same pattern as Local provider)
|
||||
- `triggerJob()`: Delegate to `this.triggerJob()`
|
||||
- `wait()`: Throw "Not implemented" (same as Local provider). No handler uses `io.wait()` so this has zero impact
|
||||
- `logger`: Same console-based logger pattern as Local provider
|
||||
|
||||
### Phase 2: Provider Registration
|
||||
|
||||
**File: `packages/lib/jobs/client/client.ts`**
|
||||
|
||||
Add `'bullmq'` case to the provider match:
|
||||
|
||||
```typescript
|
||||
this._provider = match(env('NEXT_PRIVATE_JOBS_PROVIDER'))
|
||||
.with('inngest', () => InngestJobProvider.getInstance())
|
||||
.with('bullmq', () => BullMQJobProvider.getInstance())
|
||||
.otherwise(() => LocalJobProvider.getInstance());
|
||||
```
|
||||
|
||||
**File: `packages/tsconfig/process-env.d.ts`**
|
||||
|
||||
Add `'bullmq'` to the `NEXT_PRIVATE_JOBS_PROVIDER` type union and add Redis env var types:
|
||||
|
||||
```typescript
|
||||
NEXT_PRIVATE_JOBS_PROVIDER?: 'inngest' | 'local' | 'bullmq';
|
||||
NEXT_PRIVATE_REDIS_URL?: string;
|
||||
NEXT_PRIVATE_REDIS_PREFIX?: string;
|
||||
NEXT_PRIVATE_BULLMQ_CONCURRENCY?: string;
|
||||
```
|
||||
|
||||
**File: `.env.example`**
|
||||
|
||||
Add Redis configuration examples:
|
||||
|
||||
```env
|
||||
NEXT_PRIVATE_JOBS_PROVIDER="local" # Options: local, inngest, bullmq
|
||||
NEXT_PRIVATE_REDIS_URL="redis://localhost:63790"
|
||||
NEXT_PRIVATE_REDIS_PREFIX="documenso" # Namespace for Redis keys (useful when sharing a Redis instance)
|
||||
```
|
||||
|
||||
**File: `turbo.json`**
|
||||
|
||||
Add `NEXT_PRIVATE_REDIS_URL`, `NEXT_PRIVATE_REDIS_PREFIX`, and `NEXT_PRIVATE_BULLMQ_CONCURRENCY` to the env vars list for cache invalidation.
|
||||
|
||||
### Phase 3: Infrastructure & Dependencies
|
||||
|
||||
**File: `packages/lib/package.json`**
|
||||
|
||||
Add dependencies:
|
||||
|
||||
- `bullmq` — the queue library
|
||||
- `ioredis` — Redis client (peer dependency of BullMQ, but explicit is better)
|
||||
|
||||
**File: `docker-compose.yml` (or equivalent)**
|
||||
|
||||
Add Redis service for local development:
|
||||
|
||||
```yaml
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- '6379:6379'
|
||||
```
|
||||
|
||||
### Phase 4: Optional Enhancements
|
||||
|
||||
These are not required for the initial implementation but worth considering for follow-up:
|
||||
|
||||
1. **Bull Board integration** — Add a `/api/jobs/dashboard` route that serves Bull Board UI for monitoring. Gate behind an admin auth check.
|
||||
|
||||
2. **Separate worker process** — Add an `apps/worker` entry point that runs BullMQ workers without the web server, for deployments that want to isolate job processing from request handling.
|
||||
|
||||
3. **Graceful shutdown** — Register `SIGTERM`/`SIGINT` handlers to call `worker.close()` and `queue.close()` for clean shutdown.
|
||||
|
||||
4. **BackgroundJob table integration** — Optionally continue writing to the `BackgroundJob` Prisma table for audit/history, using BullMQ events (`completed`, `failed`) to update status. This preserves the existing database-level visibility.
|
||||
|
||||
---
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
| File | Action | Description |
|
||||
| ------------------------------------ | ---------- | ---------------------------------------- |
|
||||
| `packages/lib/jobs/client/bullmq.ts` | **Create** | BullMQ provider implementation |
|
||||
| `packages/lib/jobs/client/client.ts` | Modify | Add `'bullmq'` provider case |
|
||||
| `packages/tsconfig/process-env.d.ts` | Modify | Add type for `'bullmq'` + Redis env vars |
|
||||
| `.env.example` | Modify | Add Redis config example |
|
||||
| `turbo.json` | Modify | Add Redis env var to cache keys |
|
||||
| `packages/lib/package.json` | Modify | Add `bullmq` + `ioredis` dependencies |
|
||||
| `docker-compose.yml` | Modify | Add Redis service |
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Should the BullMQ provider also write to the `BackgroundJob` Prisma table?** This would maintain audit history and allow existing admin tooling to query job status. Trade-off is dual-write complexity.
|
||||
|
||||
2. **Redis connection resilience**: Should the provider gracefully degrade if Redis is unavailable (e.g., fall back to Local provider), or fail hard? Failing hard is simpler and more predictable.
|
||||
|
||||
## Resolved Questions
|
||||
|
||||
- **`io.wait()`**: Not a concern. Only Inngest implements it (via `step.sleep`), the Local provider throws "Not implemented", and no job handler calls `io.wait()`. The BullMQ provider can throw "Not implemented" identically to the Local provider.
|
||||
|
|
@ -35,6 +35,8 @@ NEXT_PRIVATE_OIDC_PROMPT="login"
|
|||
NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
|
||||
# URL used by the web app to request itself (e.g. local background jobs)
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000"
|
||||
# OPTIONAL: Comma-separated hostnames or IPs whose webhooks are allowed to resolve to private/loopback addresses. (e.g., internal.example.com,192.168.1.5).
|
||||
NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS=
|
||||
|
||||
# [[SERVER]]
|
||||
# OPTIONAL: The port the server will listen on. Defaults to 3000.
|
||||
|
|
@ -143,8 +145,15 @@ NEXT_PRIVATE_STRIPE_API_KEY=
|
|||
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET=
|
||||
|
||||
# [[BACKGROUND JOBS]]
|
||||
# Available options: local (default) | inngest | bullmq
|
||||
NEXT_PRIVATE_JOBS_PROVIDER="local"
|
||||
NEXT_PRIVATE_INNGEST_EVENT_KEY=
|
||||
# OPTIONAL: Redis URL for the BullMQ jobs provider.
|
||||
NEXT_PRIVATE_REDIS_URL="redis://localhost:63790"
|
||||
# OPTIONAL: Key prefix for Redis to namespace queues (useful when sharing a Redis instance).
|
||||
NEXT_PRIVATE_REDIS_PREFIX="documenso"
|
||||
# OPTIONAL: Number of concurrent jobs to process. Defaults to 10.
|
||||
# NEXT_PRIVATE_BULLMQ_CONCURRENCY=10
|
||||
|
||||
# [[FEATURES]]
|
||||
# OPTIONAL: Leave blank to disable PostHog and feature flags.
|
||||
|
|
|
|||
5
.github/labeler.yml
vendored
5
.github/labeler.yml
vendored
|
|
@ -1,5 +1,8 @@
|
|||
'apps: web':
|
||||
- apps/web/**
|
||||
- apps/remix/**
|
||||
|
||||
'type: documentation':
|
||||
- apps/docs/**
|
||||
|
||||
'version bump 👀':
|
||||
- '**/package.json'
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ Processes async jobs.
|
|||
| Provider | Description | Env Value |
|
||||
| -------- | --------------------- | ----------------- |
|
||||
| Local | Database-backed queue | `local` (default) |
|
||||
| BullMQ | Redis-backed queue | `bullmq` |
|
||||
| Inngest | Managed cloud service | `inngest` |
|
||||
|
||||
**Config**: `NEXT_PRIVATE_JOBS_PROVIDER`
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
---
|
||||
title: Developer Mode
|
||||
description: Advanced development tools for debugging field coordinates and integrating with the Documenso API.
|
||||
description: Advanced development tools for debugging field IDs, recipient IDs, coordinates and integrating with the Documenso API.
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Developer mode provides additional tools and features to help you integrate and debug Documenso.
|
||||
|
||||
## Field Coordinates
|
||||
## Field Information
|
||||
|
||||
Field coordinates represent the position of a field in a document. They are returned in the `pageX`, `pageY`, `width` and `height` properties of the field.
|
||||
When enabled, developer mode displays the following information for each field:
|
||||
|
||||
To enable field coordinates, add the `devmode=true` query parameter to the editor URL.
|
||||
- **Field ID** - The unique identifier of the field
|
||||
- **Recipient ID** - The ID of the recipient assigned to the field
|
||||
- **Pos X / Pos Y** - The position of the field on the page
|
||||
- **Width / Height** - The dimensions of the field
|
||||
|
||||
To enable developer mode, add the `devmode=true` query parameter to the editor URL.
|
||||
|
||||
```bash
|
||||
# Legacy editor
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
---
|
||||
title: Background Jobs
|
||||
description: Configure how Documenso processes background tasks like email delivery, document processing, and webhook dispatch.
|
||||
---
|
||||
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
## Overview
|
||||
|
||||
Documenso processes background jobs for email delivery, document sealing, webhook dispatch, and scheduled maintenance tasks. Three providers are available:
|
||||
|
||||
| Provider | Backend | Best For | Infrastructure |
|
||||
| -------- | ---------- | ----------------------------------------------- | -------------- |
|
||||
| Inngest | Managed | Production with zero ops overhead | None |
|
||||
| BullMQ | Redis | Self-hosted production with full control | Redis |
|
||||
| Local | PostgreSQL | Development and small self-hosted deployments | None |
|
||||
|
||||
Select a provider with the `NEXT_PRIVATE_JOBS_PROVIDER` environment variable:
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_JOBS_PROVIDER=inngest # or bullmq, local
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
The default provider is `local`. It requires no additional infrastructure and works well for development and small deployments, but is not recommended for production workloads.
|
||||
</Callout>
|
||||
|
||||
---
|
||||
|
||||
## Inngest (Recommended)
|
||||
|
||||
[Inngest](https://www.inngest.com/) is a managed background job service. It handles scheduling, retries, concurrency, and observability without any infrastructure to manage. This is the recommended provider for production deployments.
|
||||
|
||||
### Setup
|
||||
|
||||
{/* prettier-ignore */}
|
||||
1. Create an account at [inngest.com](https://www.inngest.com/)
|
||||
2. Create an app and obtain your event key and signing key
|
||||
3. Configure the environment variables:
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_JOBS_PROVIDER=inngest
|
||||
NEXT_PRIVATE_INNGEST_EVENT_KEY=your-event-key
|
||||
INNGEST_SIGNING_KEY=your-signing-key
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description | Required |
|
||||
| -------------------------------- | -------------------------------------------- | -------- |
|
||||
| `NEXT_PRIVATE_INNGEST_EVENT_KEY` | Inngest event key | Yes |
|
||||
| `INNGEST_EVENT_KEY` | Alternative Inngest event key | No |
|
||||
| `INNGEST_SIGNING_KEY` | Inngest signing key for webhook verification | Yes |
|
||||
| `NEXT_PRIVATE_INNGEST_APP_ID` | Custom Inngest app ID | No |
|
||||
|
||||
### Advantages
|
||||
|
||||
- No infrastructure to manage
|
||||
- Built-in monitoring dashboard
|
||||
- Automatic retries with backoff
|
||||
- Cron scheduling handled externally
|
||||
- Scales automatically
|
||||
|
||||
---
|
||||
|
||||
## BullMQ
|
||||
|
||||
[BullMQ](https://docs.bullmq.io/) is a Redis-backed job queue that runs inside the Documenso process. It provides higher throughput than the local provider, configurable concurrency, and a built-in dashboard for monitoring jobs.
|
||||
|
||||
### Requirements
|
||||
|
||||
- **Redis 6.2+** - any Redis-compatible service works (Redis, KeyDB, Dragonfly, AWS ElastiCache, Upstash, etc.)
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_JOBS_PROVIDER=bullmq
|
||||
NEXT_PRIVATE_REDIS_URL=redis://localhost:6379
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ---------------------------------- | -------------------------------------------------------------------------- | ----------- |
|
||||
| `NEXT_PRIVATE_REDIS_URL` | Redis connection URL | _(required)_ |
|
||||
| `NEXT_PRIVATE_REDIS_PREFIX` | Key prefix for Redis queues (useful when sharing an instance) | `documenso` |
|
||||
| `NEXT_PRIVATE_BULLMQ_CONCURRENCY` | Number of concurrent jobs to process | `10` |
|
||||
|
||||
### Dashboard
|
||||
|
||||
BullMQ includes a job monitoring dashboard at `/api/jobs/board`. In production, only admin users can access the dashboard. In development, it is open to all users.
|
||||
|
||||
The dashboard provides visibility into queued, active, completed, and failed jobs.
|
||||
|
||||
### Docker Compose with Redis
|
||||
|
||||
If you're using Docker Compose, add a Redis service:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
redis:
|
||||
image: redis:8-alpine
|
||||
ports:
|
||||
- '6379:6379'
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
```
|
||||
|
||||
Then set `NEXT_PRIVATE_REDIS_URL=redis://redis:6379` in your Documenso environment.
|
||||
|
||||
### Advantages
|
||||
|
||||
- Self-hosted with no external service dependencies beyond Redis
|
||||
- Configurable concurrency
|
||||
- Built-in job monitoring dashboard
|
||||
- Reliable retries with exponential backoff
|
||||
- Queue namespacing for shared Redis instances
|
||||
|
||||
---
|
||||
|
||||
## Local
|
||||
|
||||
The local provider uses your PostgreSQL database as a job queue. Jobs are stored in the `BackgroundJob` table and processed via internal HTTP requests that Documenso sends to itself.
|
||||
|
||||
### Setup
|
||||
|
||||
No configuration required. The local provider is the default when `NEXT_PRIVATE_JOBS_PROVIDER` is unset or set to `local`.
|
||||
|
||||
```bash
|
||||
# Optional - this is the default
|
||||
NEXT_PRIVATE_JOBS_PROVIDER=local
|
||||
```
|
||||
|
||||
### Internal URL
|
||||
|
||||
Background jobs in the local provider work by Documenso sending HTTP requests to itself. If your reverse proxy or network setup causes issues with the app reaching its own public URL, set the internal URL:
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL=http://localhost:3000
|
||||
```
|
||||
|
||||
This tells the job system to use the internal address instead of `NEXT_PUBLIC_WEBAPP_URL` for self-requests.
|
||||
|
||||
<Callout type="warn">
|
||||
The local provider is suitable for development and small deployments. For production workloads, use Inngest or BullMQ.
|
||||
</Callout>
|
||||
|
||||
### Limitations
|
||||
|
||||
- No concurrency control - jobs are processed one at a time per request cycle
|
||||
- No built-in monitoring
|
||||
- Depends on the application being able to reach itself over HTTP
|
||||
- Not suitable for high-throughput workloads
|
||||
|
||||
---
|
||||
|
||||
## Choosing a Provider
|
||||
|
||||
<Tabs items={['Managed hosting', 'Self-hosted production', 'Development']}>
|
||||
<Tab value="Managed hosting">
|
||||
|
||||
Use **Inngest**. Zero infrastructure, automatic scaling, and built-in observability. The simplest path to reliable background jobs in production.
|
||||
|
||||
</Tab>
|
||||
<Tab value="Self-hosted production">
|
||||
|
||||
Use **BullMQ**. Add a Redis instance to your infrastructure and get reliable job processing with a monitoring dashboard. Good fit if you already run Redis or want to keep everything self-hosted.
|
||||
|
||||
</Tab>
|
||||
<Tab value="Development">
|
||||
|
||||
Use **Local** (the default). No additional setup required. Works out of the box with just PostgreSQL.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Environment Variables](/docs/self-hosting/configuration/environment) - Complete configuration reference
|
||||
- [Requirements](/docs/self-hosting/getting-started/requirements) - Infrastructure requirements
|
||||
- [Docker Compose](/docs/self-hosting/deployment/docker-compose) - Deploy with Docker Compose
|
||||
|
|
@ -268,20 +268,40 @@ AI features must also be enabled in organisation/team settings after configurati
|
|||
|
||||
## Background Jobs
|
||||
|
||||
Documenso uses a PostgreSQL-based job queue by default. Jobs (email delivery, document processing, webhook dispatch) are stored in the `BackgroundJob` table and processed via internal HTTP requests. No external queue service like Redis is required.
|
||||
Documenso supports multiple background job providers for processing emails, documents, webhooks, and scheduled tasks.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------ | ------- |
|
||||
| `NEXT_PRIVATE_JOBS_PROVIDER` | Jobs provider: `local` (PostgreSQL-based queue) or `inngest` (managed service) | `local` |
|
||||
### Provider Selection
|
||||
|
||||
### Inngest Configuration
|
||||
| Variable | Description | Default |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------- | ------- |
|
||||
| `NEXT_PRIVATE_JOBS_PROVIDER` | Jobs provider: `local` (PostgreSQL), `bullmq` (Redis), or `inngest` (managed service) | `local` |
|
||||
|
||||
| Variable | Description |
|
||||
| -------------------------------- | -------------------------------------------- |
|
||||
| `NEXT_PRIVATE_INNGEST_EVENT_KEY` | Inngest event key |
|
||||
| `INNGEST_EVENT_KEY` | Alternative Inngest event key |
|
||||
| `INNGEST_SIGNING_KEY` | Inngest signing key for webhook verification |
|
||||
| `NEXT_PRIVATE_INNGEST_APP_ID` | Custom Inngest app ID |
|
||||
### Local (local)
|
||||
|
||||
No additional configuration required. Jobs are stored in PostgreSQL and processed via internal HTTP requests.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ---------------------------------- | ------------------------------------------------------------ | -------------------------------- |
|
||||
| `NEXT_PRIVATE_INTERNAL_WEBAPP_URL` | Internal URL for the app to send job requests to itself | Same as `NEXT_PUBLIC_WEBAPP_URL` |
|
||||
|
||||
### BullMQ (bullmq)
|
||||
|
||||
| Variable | Required | Description | Default |
|
||||
| ---------------------------------- | -------- | ------------------------------------------------------------- | ----------- |
|
||||
| `NEXT_PRIVATE_REDIS_URL` | Yes | Redis connection URL (e.g., `redis://localhost:6379`) | |
|
||||
| `NEXT_PRIVATE_REDIS_PREFIX` | No | Key prefix for Redis queues (useful when sharing an instance) | `documenso` |
|
||||
| `NEXT_PRIVATE_BULLMQ_CONCURRENCY` | No | Number of concurrent jobs to process | `10` |
|
||||
|
||||
### Inngest (inngest)
|
||||
|
||||
| Variable | Required | Description |
|
||||
| -------------------------------- | -------- | -------------------------------------------- |
|
||||
| `NEXT_PRIVATE_INNGEST_EVENT_KEY` | Yes | Inngest event key |
|
||||
| `INNGEST_EVENT_KEY` | No | Alternative Inngest event key |
|
||||
| `INNGEST_SIGNING_KEY` | Yes | Inngest signing key for webhook verification |
|
||||
| `NEXT_PRIVATE_INNGEST_APP_ID` | No | Custom Inngest app ID |
|
||||
|
||||
For setup guides and provider recommendations, see [Background Jobs](/docs/self-hosting/configuration/background-jobs).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"database",
|
||||
"email",
|
||||
"storage",
|
||||
"background-jobs",
|
||||
"signing-certificate",
|
||||
"telemetry",
|
||||
"advanced"
|
||||
|
|
|
|||
|
|
@ -85,9 +85,13 @@ See [Storage Configuration](/docs/self-hosting/configuration/storage) for setup
|
|||
|
||||
### Background Jobs
|
||||
|
||||
Documenso processes background jobs (email delivery, document processing) using a PostgreSQL-based queue. No additional services like Redis are required: the job queue is built into the application and uses your existing database.
|
||||
Documenso processes background jobs (email delivery, document processing) using a PostgreSQL-based queue by default. No additional services are required: the job queue is built into the application and uses your existing database.
|
||||
|
||||
For high-throughput deployments, Documenso optionally supports [Inngest](https://www.inngest.com/) as an alternative job provider. Set `NEXT_PRIVATE_JOBS_PROVIDER=inngest` and configure `INNGEST_EVENT_KEY` and `INNGEST_SIGNING_KEY`. Most self-hosted instances do not need this.
|
||||
For production deployments that need higher throughput or more reliable job processing, Documenso supports [BullMQ](https://docs.bullmq.io/) as an alternative provider. BullMQ requires a **Redis** instance (v6.2+). Set `NEXT_PRIVATE_JOBS_PROVIDER=bullmq` and configure `NEXT_PRIVATE_REDIS_URL`.
|
||||
|
||||
For managed/cloud deployments, [Inngest](https://www.inngest.com/) is also supported as a job provider. Set `NEXT_PRIVATE_JOBS_PROVIDER=inngest` and configure `INNGEST_EVENT_KEY` and `INNGEST_SIGNING_KEY`.
|
||||
|
||||
See [Background Jobs Configuration](/docs/self-hosting/configuration/background-jobs) for full details.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -144,19 +144,13 @@ See [Storage Configuration](/docs/self-hosting/configuration/storage) for full s
|
|||
|
||||
---
|
||||
|
||||
## Background Jobs Don't Need Redis
|
||||
## Background Jobs
|
||||
|
||||
Documenso uses a PostgreSQL-based job queue by default. No Redis, no external message broker. The job system uses your existing database to store and process background tasks like email delivery and document processing.
|
||||
Documenso uses a PostgreSQL-based job queue by default (`local` provider). No Redis or external message broker is required for basic deployments.
|
||||
|
||||
For high-throughput deployments, Documenso optionally supports [Inngest](https://www.inngest.com/) as an alternative job provider:
|
||||
For production workloads, consider switching to **Inngest** (managed) or **BullMQ** (self-hosted with Redis) for better reliability and throughput.
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_JOBS_PROVIDER=inngest
|
||||
INNGEST_EVENT_KEY=your-event-key
|
||||
INNGEST_SIGNING_KEY=your-signing-key
|
||||
```
|
||||
|
||||
Most self-hosted instances do not need Inngest.
|
||||
See [Background Jobs Configuration](/docs/self-hosting/configuration/background-jobs) for setup instructions and provider comparison.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -24,4 +24,9 @@ description: Advanced document features including PDF placeholders, AI detection
|
|||
description="Control who can see documents within a team."
|
||||
href="/docs/users/documents/advanced/document-visibility"
|
||||
/>
|
||||
<Card
|
||||
title="Recipient Expiration"
|
||||
description="Set a signing deadline so document links expire after a configurable period."
|
||||
href="/docs/users/documents/advanced/recipient-expiration"
|
||||
/>
|
||||
</Cards>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"pdf-placeholders",
|
||||
"ai-detection",
|
||||
"default-recipients",
|
||||
"document-visibility"
|
||||
"document-visibility",
|
||||
"recipient-expiration"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
---
|
||||
title: Recipient Expiration
|
||||
description: Set a signing deadline for recipients so document links expire after a configurable period.
|
||||
---
|
||||
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
## Overview
|
||||
|
||||
Recipient expiration lets you set a deadline for how long recipients have to sign a document after it is sent. Once the deadline passes, the recipient can no longer access the signing link and the document owner is notified.
|
||||
|
||||
This is useful when:
|
||||
|
||||
- A business deal is contingent on being signed within a specific time frame
|
||||
- A document is no longer relevant after a certain date
|
||||
- You want to ensure recipients act promptly rather than leaving documents unsigned indefinitely
|
||||
|
||||
Expiration is tracked **per recipient**, not per document. If one recipient's deadline passes, other recipients can still sign. The document stays in a pending state so the owner can decide whether to resend or cancel.
|
||||
|
||||
## Default Behaviour
|
||||
|
||||
Every organisation has a default expiration period of **3 months**. This means that when you send a document, each recipient has 3 months from the time the document is sent to complete their signing.
|
||||
|
||||
You can change this default at the organisation or team level, or override it per document.
|
||||
|
||||
## Settings Cascade
|
||||
|
||||
Expiration settings follow a three-level cascade: **Organisation → Team → Document**. Each level can override the one above it.
|
||||
|
||||
<Tabs items={['Organisation', 'Team', 'Document']}>
|
||||
<Tab value="Organisation">
|
||||
|
||||
Sets the default for all teams in the organisation. Options are a **custom duration** or **never expires**.
|
||||
|
||||
To configure, navigate to **Organisation Settings > Preferences > Document** and find **Default Envelope Expiration**.
|
||||
|
||||
</Tab>
|
||||
<Tab value="Team">
|
||||
|
||||
Overrides the organisation default for documents created within this team. Options are a **custom duration**, **never expires**, or **inherit from organisation**.
|
||||
|
||||
New teams default to **inherit from organisation**.
|
||||
|
||||
To configure, navigate to **Team Settings > Preferences > Document** and find **Default Envelope Expiration**.
|
||||
|
||||
</Tab>
|
||||
<Tab value="Document">
|
||||
|
||||
Overrides the team or organisation default for a single document. Options are a **custom duration** or **never expires**.
|
||||
|
||||
If you do not change the expiration when editing a document, the team or organisation default applies.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Set Expiration for a Document
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Steps>
|
||||
<Step>
|
||||
|
||||
### Open the document settings
|
||||
|
||||
In the document editor, open the **Settings** dialog and go to the **General** tab.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
|
||||
### Configure the expiration
|
||||
|
||||
Find the **Expiration** field. Choose one of:
|
||||
|
||||
- **Custom duration** — enter a number and select a unit (days, weeks, months, or years)
|
||||
- **Never expires** — the recipient can sign at any time
|
||||
|
||||
If you leave it unchanged, the team or organisation default applies.
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
|
||||
### Send the document
|
||||
|
||||
When you send the document, the expiration deadline is calculated from that moment. For example, if you set a 7-day expiration and send the document on March 1st, the recipient has until March 8th to sign.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
You cannot change the expiration period after the document has been sent. To extend a recipient's
|
||||
deadline, resend the document to them — this resets the clock.
|
||||
</Callout>
|
||||
|
||||
## Set a Default Expiration Period
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Steps>
|
||||
<Step>
|
||||
|
||||
### Navigate to document preferences
|
||||
|
||||
Go to **Organisation Settings > Preferences > Document** (or **Team Settings > Preferences > Document** for team-level overrides).
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
|
||||
### Configure the default
|
||||
|
||||
Find **Default Envelope Expiration** and choose:
|
||||
|
||||
- **Custom duration** — enter a number and unit
|
||||
- **Never expires** — no deadline for recipients
|
||||
- **Inherit from organisation** (team level only) — use whatever the organisation has configured
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
|
||||
### Save
|
||||
|
||||
Click **Save** to apply. New documents created after this change use the updated default.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Changing the default expiration does not affect documents that have already been sent. Only new
|
||||
documents use the updated setting.
|
||||
</Callout>
|
||||
|
||||
## What Happens When a Recipient Expires
|
||||
|
||||
When a recipient's signing deadline passes:
|
||||
|
||||
1. The recipient can no longer access the signing link. They see a message explaining that the signing deadline has expired and to contact the document owner.
|
||||
2. The document owner receives an email notification with a link to view the document.
|
||||
3. An audit log entry is created recording the expiration.
|
||||
4. The document remains in a **pending** state — other recipients who have not expired can still sign.
|
||||
|
||||

|
||||
|
||||
## Resending to Extend a Deadline
|
||||
|
||||
If a recipient's deadline has passed (or is about to), you can resend the document to them. Resending recalculates the expiration from the current time, effectively extending the deadline.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Steps>
|
||||
<Step>
|
||||
|
||||
### Open the document
|
||||
|
||||
Navigate to the document page and find the recipient whose deadline has expired. Expired recipients are marked with an **Expired** badge.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
|
||||
### Resend
|
||||
|
||||
Click the resend option for the recipient. This sends a new signing link and resets the expiration clock based on the document's configured expiration period.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Expiration Options Reference
|
||||
|
||||
| Unit | Example | Description |
|
||||
| ------ | --------------- | ------------------------------------------- |
|
||||
| Days | 7 days | Recipient has 7 days from when the document is sent |
|
||||
| Weeks | 2 weeks | Recipient has 2 weeks from when the document is sent |
|
||||
| Months | 3 months | Recipient has 3 months from when the document is sent (default) |
|
||||
| Years | 1 year | Recipient has 1 year from when the document is sent |
|
||||
|
||||
You can also set expiration to **never expires**, which means the signing link remains valid indefinitely.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Send Documents](/docs/users/documents/send) - Send documents for signing
|
||||
- [Document Preferences](/docs/users/organisations/preferences/document) - Configure default document settings
|
||||
- [Add Recipients](/docs/users/documents/add-recipients) - Add signers and other recipients to a document
|
||||
|
|
@ -32,6 +32,7 @@ To access the preferences, navigate to either the organisation or teams settings
|
|||
| **Include the Signing Certificate** | Whether the signing certificate is embedded in signed PDFs. The certificate is always available separately from the logs page. |
|
||||
| **Include the Audit Logs** | Whether the audit logs are embedded in the document when downloaded. The audit logs are always available separately from the logs page. |
|
||||
| **Default Recipients** | Recipients that are automatically added to new documents. Can be overridden per document. |
|
||||
| **Default Envelope Expiration** | How long recipients have to sign before the signing link expires. See [recipient expiration](/docs/users/documents/advanced/recipient-expiration). |
|
||||
| **Delegate Document Ownership** | Allow team API tokens to delegate document ownership to another team member. |
|
||||
| **AI Features** | Enable AI-powered features such as automatic recipient detection. Only shown if AI features are configured on the instance. |
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 596 KiB After Width: | Height: | Size: 117 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 571 KiB After Width: | Height: | Size: 126 KiB |
BIN
apps/docs/public/recipient-expiration/configure-expiration.webp
Normal file
BIN
apps/docs/public/recipient-expiration/configure-expiration.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
BIN
apps/docs/public/recipient-expiration/recipient-expired.webp
Normal file
BIN
apps/docs/public/recipient-expiration/recipient-expired.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
|
|
@ -5,6 +5,7 @@ import { Trans, useLingui } from '@lingui/react/macro';
|
|||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
|
|
@ -43,7 +44,7 @@ type ConfirmationDialogProps = {
|
|||
|
||||
const ZNextSignerFormSchema = z.object({
|
||||
name: z.string().min(1, 'Name is required'),
|
||||
email: z.string().email('Invalid email address'),
|
||||
email: zEmail('Invalid email address'),
|
||||
});
|
||||
|
||||
type TNextSignerFormSchema = z.infer<typeof ZNextSignerFormSchema>;
|
||||
|
|
|
|||
|
|
@ -1,201 +0,0 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { DocumentStatus } from '@prisma/client';
|
||||
import { P, match } from 'ts-pattern';
|
||||
|
||||
import { useLimits } from '@documenso/ee/server-only/limits/provider/client';
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { Alert, AlertDescription } from '@documenso/ui/primitives/alert';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
type DocumentDeleteDialogProps = {
|
||||
id: number;
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
onDelete?: () => Promise<void> | void;
|
||||
status: DocumentStatus;
|
||||
documentTitle: string;
|
||||
canManageDocument: boolean;
|
||||
};
|
||||
|
||||
export const DocumentDeleteDialog = ({
|
||||
id,
|
||||
open,
|
||||
onOpenChange,
|
||||
onDelete,
|
||||
status,
|
||||
documentTitle,
|
||||
canManageDocument,
|
||||
}: DocumentDeleteDialogProps) => {
|
||||
const { toast } = useToast();
|
||||
const { refreshLimits } = useLimits();
|
||||
const { _ } = useLingui();
|
||||
|
||||
const deleteMessage = msg`delete`;
|
||||
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [isDeleteEnabled, setIsDeleteEnabled] = useState(status === DocumentStatus.DRAFT);
|
||||
|
||||
const { mutateAsync: deleteDocument, isPending } = trpcReact.document.delete.useMutation({
|
||||
onSuccess: async () => {
|
||||
void refreshLimits();
|
||||
|
||||
toast({
|
||||
title: _(msg`Document deleted`),
|
||||
description: _(msg`"${documentTitle}" has been successfully deleted`),
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
await onDelete?.();
|
||||
|
||||
onOpenChange(false);
|
||||
},
|
||||
onError: () => {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`This document could not be deleted at this time. Please try again.`),
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setInputValue('');
|
||||
setIsDeleteEnabled(status === DocumentStatus.DRAFT);
|
||||
}
|
||||
}, [open, status]);
|
||||
|
||||
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setInputValue(event.target.value);
|
||||
setIsDeleteEnabled(event.target.value === _(deleteMessage));
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(value) => !isPending && onOpenChange(value)}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Are you sure?</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogDescription>
|
||||
{canManageDocument ? (
|
||||
<Trans>
|
||||
You are about to delete <strong>"{documentTitle}"</strong>
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
You are about to hide <strong>"{documentTitle}"</strong>
|
||||
</Trans>
|
||||
)}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{canManageDocument ? (
|
||||
<Alert variant="warning" className="-mt-1">
|
||||
{match(status)
|
||||
.with(DocumentStatus.DRAFT, () => (
|
||||
<AlertDescription>
|
||||
<Trans>
|
||||
Please note that this action is <strong>irreversible</strong>. Once confirmed,
|
||||
this document will be permanently deleted.
|
||||
</Trans>
|
||||
</AlertDescription>
|
||||
))
|
||||
.with(DocumentStatus.PENDING, () => (
|
||||
<AlertDescription>
|
||||
<p>
|
||||
<Trans>
|
||||
Please note that this action is <strong>irreversible</strong>.
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<p className="mt-1">
|
||||
<Trans>Once confirmed, the following will occur:</Trans>
|
||||
</p>
|
||||
|
||||
<ul className="mt-0.5 list-inside list-disc">
|
||||
<li>
|
||||
<Trans>Document will be permanently deleted</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>Document signing process will be cancelled</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>All inserted signatures will be voided</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>All recipients will be notified</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</AlertDescription>
|
||||
))
|
||||
.with(P.union(DocumentStatus.COMPLETED, DocumentStatus.REJECTED), () => (
|
||||
<AlertDescription>
|
||||
<p>
|
||||
<Trans>By deleting this document, the following will occur:</Trans>
|
||||
</p>
|
||||
|
||||
<ul className="mt-0.5 list-inside list-disc">
|
||||
<li>
|
||||
<Trans>The document will be hidden from your account</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>Recipients will still retain their copy of the document</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</AlertDescription>
|
||||
))
|
||||
.exhaustive()}
|
||||
</Alert>
|
||||
) : (
|
||||
<Alert variant="warning" className="-mt-1">
|
||||
<AlertDescription>
|
||||
<Trans>Please contact support if you would like to revert this action.</Trans>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{status !== DocumentStatus.DRAFT && canManageDocument && (
|
||||
<Input
|
||||
type="text"
|
||||
value={inputValue}
|
||||
onChange={onInputChange}
|
||||
placeholder={_(msg`Please type ${`'${_(deleteMessage)}'`} to confirm`)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="secondary" onClick={() => onOpenChange(false)}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
loading={isPending}
|
||||
onClick={() => void deleteDocument({ documentId: id })}
|
||||
disabled={!isDeleteEnabled && canManageDocument}
|
||||
variant="destructive"
|
||||
>
|
||||
{canManageDocument ? _(msg`Delete`) : _(msg`Hide`)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
|
||||
type DocumentDuplicateDialogProps = {
|
||||
id: string;
|
||||
token?: string;
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
};
|
||||
|
||||
export const DocumentDuplicateDialog = ({
|
||||
id,
|
||||
token,
|
||||
open,
|
||||
onOpenChange,
|
||||
}: DocumentDuplicateDialogProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { toast } = useToast();
|
||||
const { _ } = useLingui();
|
||||
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const documentsPath = formatDocumentsPath(team.url);
|
||||
|
||||
const { mutateAsync: duplicateEnvelope, isPending: isDuplicating } =
|
||||
trpcReact.envelope.duplicate.useMutation({
|
||||
onSuccess: async ({ id }) => {
|
||||
toast({
|
||||
title: _(msg`Document Duplicated`),
|
||||
description: _(msg`Your document has been successfully duplicated.`),
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
await navigate(`${documentsPath}/${id}/edit`);
|
||||
onOpenChange(false);
|
||||
},
|
||||
});
|
||||
|
||||
const onDuplicate = async () => {
|
||||
try {
|
||||
await duplicateEnvelope({ envelopeId: id });
|
||||
} catch {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`This document could not be duplicated at this time. Please try again.`),
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(value) => !isDuplicating && onOpenChange(value)}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Duplicate</Trans>
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogFooter>
|
||||
<div className="flex w-full flex-1 flex-nowrap gap-4">
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => onOpenChange(false)}
|
||||
className="flex-1"
|
||||
>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isDuplicating}
|
||||
loading={isDuplicating}
|
||||
onClick={onDuplicate}
|
||||
className="flex-1"
|
||||
>
|
||||
<Trans>Duplicate</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -52,13 +52,23 @@ export const EnvelopeDeleteDialog = ({
|
|||
const [inputValue, setInputValue] = useState('');
|
||||
const [isDeleteEnabled, setIsDeleteEnabled] = useState(status === DocumentStatus.DRAFT);
|
||||
|
||||
const isDocument = type === EnvelopeType.DOCUMENT;
|
||||
|
||||
const { mutateAsync: deleteEnvelope, isPending } = trpcReact.envelope.delete.useMutation({
|
||||
onSuccess: async () => {
|
||||
void refreshLimits();
|
||||
|
||||
toast({
|
||||
title: t`Document deleted`,
|
||||
description: t`"${title}" has been successfully deleted`,
|
||||
title: canManageDocument
|
||||
? isDocument
|
||||
? t`Document deleted`
|
||||
: t`Template deleted`
|
||||
: isDocument
|
||||
? t`Document hidden`
|
||||
: t`Template hidden`,
|
||||
description: canManageDocument
|
||||
? t`"${title}" has been successfully deleted`
|
||||
: t`"${title}" has been successfully hidden`,
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
|
|
@ -69,7 +79,9 @@ export const EnvelopeDeleteDialog = ({
|
|||
onError: () => {
|
||||
toast({
|
||||
title: t`Something went wrong`,
|
||||
description: t`This document could not be deleted at this time. Please try again.`,
|
||||
description: isDocument
|
||||
? t`This document could not be deleted at this time. Please try again.`
|
||||
: t`This template could not be deleted at this time. Please try again.`,
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/org
|
|||
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
|
||||
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
||||
import { getRecipientsWithMissingFields } from '@documenso/lib/utils/recipients';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc, trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
|
|
@ -62,10 +63,7 @@ export type EnvelopeDistributeDialogProps = {
|
|||
export const ZEnvelopeDistributeFormSchema = z.object({
|
||||
meta: z.object({
|
||||
emailId: z.string().nullable(),
|
||||
emailReplyTo: z.preprocess(
|
||||
(val) => (val === '' ? undefined : val),
|
||||
z.string().email().optional(),
|
||||
),
|
||||
emailReplyTo: z.preprocess((val) => (val === '' ? undefined : val), zEmail().optional()),
|
||||
subject: z.string(),
|
||||
message: z.string(),
|
||||
distributionMethod: z
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
|
|
@ -10,6 +9,7 @@ import { trpc } from '@documenso/trpc/react';
|
|||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
|
|
@ -41,19 +41,20 @@ export const EnvelopeDuplicateDialog = ({
|
|||
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const isDocument = envelopeType === EnvelopeType.DOCUMENT;
|
||||
|
||||
const { mutateAsync: duplicateEnvelope, isPending: isDuplicating } =
|
||||
trpc.envelope.duplicate.useMutation({
|
||||
onSuccess: async ({ id }) => {
|
||||
toast({
|
||||
title: t`Envelope Duplicated`,
|
||||
description: t`Your envelope has been successfully duplicated.`,
|
||||
title: isDocument ? t`Document Duplicated` : t`Template Duplicated`,
|
||||
description: isDocument
|
||||
? t`Your document has been successfully duplicated.`
|
||||
: t`Your template has been successfully duplicated.`,
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
const path =
|
||||
envelopeType === EnvelopeType.DOCUMENT
|
||||
? formatDocumentsPath(team.url)
|
||||
: formatTemplatesPath(team.url);
|
||||
const path = isDocument ? formatDocumentsPath(team.url) : formatTemplatesPath(team.url);
|
||||
|
||||
await navigate(`${path}/${id}/edit`);
|
||||
setOpen(false);
|
||||
|
|
@ -66,7 +67,9 @@ export const EnvelopeDuplicateDialog = ({
|
|||
} catch {
|
||||
toast({
|
||||
title: t`Something went wrong`,
|
||||
description: t`This document could not be duplicated at this time. Please try again.`,
|
||||
description: isDocument
|
||||
? t`This document could not be duplicated at this time. Please try again.`
|
||||
: t`This template could not be duplicated at this time. Please try again.`,
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
|
|
@ -78,30 +81,25 @@ export const EnvelopeDuplicateDialog = ({
|
|||
{trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
|
||||
|
||||
<DialogContent>
|
||||
{envelopeType === EnvelopeType.DOCUMENT ? (
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Duplicate Document</Trans>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{isDocument ? <Trans>Duplicate Document</Trans> : <Trans>Duplicate Template</Trans>}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{isDocument ? (
|
||||
<Trans>This document will be duplicated.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
) : (
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Duplicate Template</Trans>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
) : (
|
||||
<Trans>This template will be duplicated.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
)}
|
||||
)}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="secondary" disabled={isDuplicating}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
<DialogClose asChild>
|
||||
<Button type="button" variant="secondary" disabled={isDuplicating}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
</DialogClose>
|
||||
|
||||
<Button type="button" loading={isDuplicating} onClick={onDuplicate}>
|
||||
<Trans>Duplicate</Trans>
|
||||
|
|
|
|||
130
apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
Normal file
130
apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { DOCUMENT_TITLE_MAX_LENGTH } from '@documenso/trpc/server/document-router/schema';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
export type EnvelopeRenameDialogProps = {
|
||||
id: string;
|
||||
initialTitle: string;
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
onSuccess?: () => Promise<void>;
|
||||
envelopeType?: 'document' | 'template';
|
||||
};
|
||||
|
||||
export const EnvelopeRenameDialog = ({
|
||||
id,
|
||||
initialTitle,
|
||||
open,
|
||||
onOpenChange,
|
||||
onSuccess,
|
||||
envelopeType = 'document',
|
||||
}: EnvelopeRenameDialogProps) => {
|
||||
const { toast } = useToast();
|
||||
const { t } = useLingui();
|
||||
|
||||
const [title, setTitle] = useState(initialTitle);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setTitle(initialTitle);
|
||||
}
|
||||
}, [open, initialTitle]);
|
||||
|
||||
const isTemplate = envelopeType === 'template';
|
||||
|
||||
const { mutate: updateEnvelope, isPending } = trpcReact.envelope.update.useMutation({
|
||||
onSuccess: async () => {
|
||||
await onSuccess?.();
|
||||
|
||||
toast({
|
||||
title: isTemplate ? t`Template Renamed` : t`Document Renamed`,
|
||||
description: isTemplate
|
||||
? t`Your template has been successfully renamed.`
|
||||
: t`Your document has been successfully renamed.`,
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
},
|
||||
onError: () => {
|
||||
toast({
|
||||
description: t`Something went wrong. Please try again.`,
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const trimmedTitle = title.trim();
|
||||
|
||||
const onRename = () => {
|
||||
if (!trimmedTitle || trimmedTitle === initialTitle) {
|
||||
onOpenChange(false);
|
||||
return;
|
||||
}
|
||||
|
||||
updateEnvelope({
|
||||
envelopeId: id,
|
||||
data: {
|
||||
title: trimmedTitle,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(value) => !isPending && onOpenChange(value)}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{isTemplate ? <Trans>Rename Template</Trans> : <Trans>Rename Document</Trans>}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="py-2">
|
||||
<Label htmlFor="title" className="sr-only">
|
||||
<Trans>Title</Trans>
|
||||
</Label>
|
||||
<Input
|
||||
id="title"
|
||||
value={title}
|
||||
placeholder={t`Enter a new title`}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
disabled={isPending}
|
||||
maxLength={DOCUMENT_TITLE_MAX_LENGTH}
|
||||
className="w-full"
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="secondary" onClick={() => onOpenChange(false)}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isPending || !trimmedTitle || trimmedTitle === initialTitle}
|
||||
loading={isPending}
|
||||
onClick={() => void onRename()}
|
||||
>
|
||||
<Trans>Rename</Trans>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
import { formatTemplatesPath } from '@documenso/lib/utils/teams';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { Checkbox } from '@documenso/ui/primitives/checkbox';
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
|
||||
type EnvelopeSaveAsTemplateDialogProps = {
|
||||
envelopeId: string;
|
||||
trigger?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const EnvelopeSaveAsTemplateDialog = ({
|
||||
envelopeId,
|
||||
trigger,
|
||||
}: EnvelopeSaveAsTemplateDialogProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const { toast } = useToast();
|
||||
const { t } = useLingui();
|
||||
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const templatesPath = formatTemplatesPath(team.url);
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
includeRecipients: true,
|
||||
includeFields: true,
|
||||
},
|
||||
});
|
||||
|
||||
const includeRecipients = form.watch('includeRecipients');
|
||||
|
||||
const { mutateAsync: saveAsTemplate, isPending } = trpc.envelope.saveAsTemplate.useMutation({
|
||||
onSuccess: async ({ id }) => {
|
||||
toast({
|
||||
title: t`Template Created`,
|
||||
description: t`Your document has been saved as a template.`,
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
await navigate(`${templatesPath}/${id}/edit`);
|
||||
setOpen(false);
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async () => {
|
||||
const { includeRecipients, includeFields } = form.getValues();
|
||||
|
||||
try {
|
||||
await saveAsTemplate({
|
||||
envelopeId,
|
||||
includeRecipients,
|
||||
includeFields: includeRecipients && includeFields,
|
||||
});
|
||||
} catch {
|
||||
toast({
|
||||
title: t`Something went wrong`,
|
||||
description: t`This document could not be saved as a template at this time. Please try again.`,
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onOpenChange={(value) => {
|
||||
if (isPending) {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(value);
|
||||
|
||||
if (!value) {
|
||||
form.reset();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
|
||||
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Save as Template</Trans>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans>Create a template from this document.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="includeRecipients"
|
||||
render={({ field }) => (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeIncludeRecipients"
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked === true);
|
||||
|
||||
if (!checked) {
|
||||
form.setValue('includeFields', false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Label htmlFor="envelopeIncludeRecipients">
|
||||
<Trans>Include Recipients</Trans>
|
||||
</Label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="includeFields"
|
||||
render={({ field }) => (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="envelopeIncludeFields"
|
||||
checked={field.value}
|
||||
disabled={!includeRecipients}
|
||||
onCheckedChange={(checked) => field.onChange(checked === true)}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="envelopeIncludeFields"
|
||||
className={!includeRecipients ? 'opacity-50' : ''}
|
||||
>
|
||||
<Trans>Include Fields</Trans>
|
||||
</Label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button type="button" variant="secondary" disabled={isPending}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
</DialogClose>
|
||||
|
||||
<Button type="button" loading={isPending} onClick={onSubmit}>
|
||||
<Trans>Save as Template</Trans>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -17,6 +17,7 @@ import { IS_BILLING_ENABLED, SUPPORT_EMAIL } from '@documenso/lib/constants/app'
|
|||
import { ORGANISATION_MEMBER_ROLE_HIERARCHY } from '@documenso/lib/constants/organisations';
|
||||
import { ORGANISATION_MEMBER_ROLE_MAP } from '@documenso/lib/constants/organisations-translations';
|
||||
import { INTERNAL_CLAIM_ID } from '@documenso/lib/types/subscription';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { ZCreateOrganisationMemberInvitesRequestSchema } from '@documenso/trpc/server/organisation-router/create-organisation-member-invites.types';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
|
|
@ -94,7 +95,7 @@ type TabTypes = 'INDIVIDUAL' | 'BULK';
|
|||
|
||||
const ZImportOrganisationMemberSchema = z.array(
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
email: zEmail(),
|
||||
organisationRole: z.nativeEnum(OrganisationMemberRole),
|
||||
}),
|
||||
);
|
||||
|
|
@ -329,12 +330,12 @@ export const OrganisationMemberInviteDialog = ({
|
|||
onValueChange={(value) => setInvitationType(value as TabTypes)}
|
||||
>
|
||||
<TabsList className="w-full">
|
||||
<TabsTrigger value="INDIVIDUAL" className="hover:text-foreground w-full">
|
||||
<TabsTrigger value="INDIVIDUAL" className="w-full hover:text-foreground">
|
||||
<MailIcon size={20} className="mr-2" />
|
||||
<Trans>Invite Members</Trans>
|
||||
</TabsTrigger>
|
||||
|
||||
<TabsTrigger value="BULK" className="hover:text-foreground w-full">
|
||||
<TabsTrigger value="BULK" className="w-full hover:text-foreground">
|
||||
<UsersIcon size={20} className="mr-2" /> <Trans>Bulk Import</Trans>
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
|
@ -382,7 +383,7 @@ export const OrganisationMemberInviteDialog = ({
|
|||
)}
|
||||
<FormControl>
|
||||
<Select {...field} onValueChange={field.onChange}>
|
||||
<SelectTrigger className="text-muted-foreground max-w-[200px]">
|
||||
<SelectTrigger className="max-w-[200px] text-muted-foreground">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
|
||||
|
|
@ -447,7 +448,7 @@ export const OrganisationMemberInviteDialog = ({
|
|||
<div className="mt-4 space-y-4">
|
||||
<Card gradient className="h-32">
|
||||
<CardContent
|
||||
className="text-muted-foreground/80 hover:text-muted-foreground/90 flex h-full cursor-pointer flex-col items-center justify-center rounded-lg p-0 transition-colors"
|
||||
className="flex h-full cursor-pointer flex-col items-center justify-center rounded-lg p-0 text-muted-foreground/80 transition-colors hover:text-muted-foreground/90"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
>
|
||||
<Upload className="h-5 w-5" />
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { createCallable } from 'react-call';
|
|||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
|
|
@ -24,10 +25,7 @@ import {
|
|||
import { Input } from '@documenso/ui/primitives/input';
|
||||
|
||||
const ZSignFieldEmailFormSchema = z.object({
|
||||
email: z
|
||||
.string()
|
||||
.email()
|
||||
.min(1, { message: msg`Email is required`.id }),
|
||||
email: zEmail().min(1, { message: msg`Email is required`.id }),
|
||||
});
|
||||
|
||||
type TSignFieldEmailFormSchema = z.infer<typeof ZSignFieldEmailFormSchema>;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import { Link } from 'react-router';
|
|||
import { match } from 'ts-pattern';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
|
||||
import { TEAM_MEMBER_ROLE_HIERARCHY } from '@documenso/lib/constants/teams';
|
||||
import { TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams-translations';
|
||||
import { canExecuteOrganisationAction } from '@documenso/lib/utils/organisations';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Alert, AlertDescription } from '@documenso/ui/primitives/alert';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
|
@ -73,8 +75,14 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
|||
const { toast } = useToast();
|
||||
|
||||
const team = useCurrentTeam();
|
||||
const organisation = useCurrentOrganisation();
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const canInviteOrganisationMembers = canExecuteOrganisationAction(
|
||||
'MANAGE_ORGANISATION',
|
||||
organisation.currentOrganisationRole,
|
||||
);
|
||||
|
||||
const form = useForm<TAddTeamMembersFormSchema>({
|
||||
resolver: zodResolver(ZAddTeamMembersFormSchema),
|
||||
defaultValues: {
|
||||
|
|
@ -106,7 +114,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
|||
|
||||
const onFormSubmit = async ({ members }: TAddTeamMembersFormSchema) => {
|
||||
if (members.length === 0) {
|
||||
if (hasNoAvailableMembers) {
|
||||
if (hasNoAvailableMembers && canInviteOrganisationMembers) {
|
||||
setInviteDialogOpen(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -231,7 +239,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
|||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && form.getValues('members').length === 0) {
|
||||
e.preventDefault();
|
||||
if (hasNoAvailableMembers) {
|
||||
if (hasNoAvailableMembers && canInviteOrganisationMembers) {
|
||||
setInviteDialogOpen(true);
|
||||
}
|
||||
// Don't show toast - the disabled Next button already communicates this
|
||||
|
|
@ -260,21 +268,32 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
|||
<Trans>No organisation members available</Trans>
|
||||
</h3>
|
||||
<p className="mb-6 max-w-sm text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
To add members to this team, you must first add them to the
|
||||
organisation.
|
||||
</Trans>
|
||||
{canInviteOrganisationMembers ? (
|
||||
<Trans>
|
||||
To add members to this team, you must first add them to the
|
||||
organisation.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
To add members to this team, they must first be invited to the
|
||||
organisation. Only organisation admins and managers can invite
|
||||
new members — please contact one of them to invite members on
|
||||
your behalf.
|
||||
</Trans>
|
||||
)}
|
||||
</p>
|
||||
<OrganisationMemberInviteDialog
|
||||
open={inviteDialogOpen}
|
||||
onOpenChange={setInviteDialogOpen}
|
||||
trigger={
|
||||
<Button type="button" variant="default">
|
||||
<UserPlusIcon className="mr-2 h-4 w-4" />
|
||||
<Trans>Invite organisation members</Trans>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
{canInviteOrganisationMembers && (
|
||||
<OrganisationMemberInviteDialog
|
||||
open={inviteDialogOpen}
|
||||
onOpenChange={setInviteDialogOpen}
|
||||
trigger={
|
||||
<Button type="button" variant="default">
|
||||
<UserPlusIcon className="mr-2 h-4 w-4" />
|
||||
<Trans>Invite organisation members</Trans>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<MultiSelectCombobox
|
||||
|
|
@ -310,30 +329,32 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi
|
|||
<Trans>Select members to add to this team</Trans>
|
||||
</FormDescription>
|
||||
|
||||
<Alert
|
||||
variant="neutral"
|
||||
className="mt-2 flex items-center gap-2 space-y-0"
|
||||
>
|
||||
<div>
|
||||
<UserPlusIcon className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
<AlertDescription className="mt-0 flex-1">
|
||||
<Trans>Can't find someone?</Trans>{' '}
|
||||
<OrganisationMemberInviteDialog
|
||||
open={inviteDialogOpen}
|
||||
onOpenChange={setInviteDialogOpen}
|
||||
trigger={
|
||||
<Button
|
||||
type="button"
|
||||
variant="link"
|
||||
className="h-auto p-0 text-sm font-medium text-documenso-700 hover:text-documenso-600"
|
||||
>
|
||||
<Trans>Invite them to the organisation first</Trans>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
{canInviteOrganisationMembers && (
|
||||
<Alert
|
||||
variant="neutral"
|
||||
className="mt-2 flex items-center gap-2 space-y-0"
|
||||
>
|
||||
<div>
|
||||
<UserPlusIcon className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
<AlertDescription className="mt-0 flex-1">
|
||||
<Trans>Can't find someone?</Trans>{' '}
|
||||
<OrganisationMemberInviteDialog
|
||||
open={inviteDialogOpen}
|
||||
onOpenChange={setInviteDialogOpen}
|
||||
trigger={
|
||||
<Button
|
||||
type="button"
|
||||
variant="link"
|
||||
className="h-auto p-0 text-sm font-medium text-documenso-700 hover:text-documenso-600"
|
||||
>
|
||||
<Trans>Invite them to the organisation first</Trans>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
type TemplateDeleteDialogProps = {
|
||||
id: number;
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
onDelete?: () => Promise<void> | void;
|
||||
};
|
||||
|
||||
export const TemplateDeleteDialog = ({
|
||||
id,
|
||||
open,
|
||||
onOpenChange,
|
||||
onDelete,
|
||||
}: TemplateDeleteDialogProps) => {
|
||||
const { _ } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const { mutateAsync: deleteTemplate, isPending } = trpcReact.template.deleteTemplate.useMutation({
|
||||
onSuccess: async () => {
|
||||
await onDelete?.();
|
||||
|
||||
toast({
|
||||
title: _(msg`Template deleted`),
|
||||
description: _(msg`Your template has been successfully deleted.`),
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
},
|
||||
onError: () => {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
description: _(msg`This template could not be deleted at this time. Please try again.`),
|
||||
variant: 'destructive',
|
||||
duration: 7500,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(value) => !isPending && onOpenChange(value)}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Do you want to delete this template?</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogDescription>
|
||||
<Trans>
|
||||
Please note that this action is irreversible. Once confirmed, your template will be
|
||||
permanently deleted.
|
||||
</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
disabled={isPending}
|
||||
onClick={() => onOpenChange(false)}
|
||||
>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
loading={isPending}
|
||||
onClick={async () => deleteTemplate({ templateId: id })}
|
||||
>
|
||||
<Trans>Delete</Trans>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@documenso/ui/primitives/dialog';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
type TemplateDuplicateDialogProps = {
|
||||
id: number;
|
||||
open: boolean;
|
||||
onOpenChange: (_open: boolean) => void;
|
||||
};
|
||||
|
||||
export const TemplateDuplicateDialog = ({
|
||||
id,
|
||||
open,
|
||||
onOpenChange,
|
||||
}: TemplateDuplicateDialogProps) => {
|
||||
const { _ } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const { mutateAsync: duplicateTemplate, isPending } =
|
||||
trpcReact.template.duplicateTemplate.useMutation({
|
||||
onSuccess: () => {
|
||||
toast({
|
||||
title: _(msg`Template duplicated`),
|
||||
description: _(msg`Your template has been duplicated successfully.`),
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
},
|
||||
onError: () => {
|
||||
toast({
|
||||
title: _(msg`Error`),
|
||||
description: _(msg`An error occurred while duplicating template.`),
|
||||
variant: 'destructive',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(value) => !isPending && onOpenChange(value)}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Do you want to duplicate this template?</Trans>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogDescription className="pt-2">
|
||||
<Trans>Your template will be duplicated.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isPending}
|
||||
variant="secondary"
|
||||
onClick={() => onOpenChange(false)}
|
||||
>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
loading={isPending}
|
||||
onClick={async () =>
|
||||
duplicateTemplate({
|
||||
templateId: id,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Trans>Duplicate</Trans>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
|
@ -6,6 +6,7 @@ import {
|
|||
ZDocumentMetaLanguageSchema,
|
||||
} from '@documenso/lib/types/document-meta';
|
||||
import { ZRecipientEmailSchema } from '@documenso/lib/types/recipient';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { DocumentDistributionMethod } from '@documenso/prisma/generated/types';
|
||||
|
||||
// Define the schema for configuration
|
||||
|
|
@ -19,7 +20,7 @@ export const ZConfigureEmbedFormSchema = z.object({
|
|||
nativeId: z.number().optional(),
|
||||
formId: z.string(),
|
||||
name: z.string(),
|
||||
email: z.string().email('Invalid email address'),
|
||||
email: zEmail('Invalid email address'),
|
||||
role: z.enum(['SIGNER', 'CC', 'APPROVER', 'VIEWER', 'ASSISTANT']),
|
||||
signingOrder: z.number().optional(),
|
||||
disabled: z.boolean().optional(),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import {
|
|||
import { LucideChevronDown, LucideChevronUp } from 'lucide-react';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useSearchParams } from 'react-router';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useThrottleFn } from '@documenso/lib/client-only/hooks/use-throttle-fn';
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||
|
|
@ -29,6 +28,7 @@ import {
|
|||
import { getDocumentDataUrlForPdfViewer } from '@documenso/lib/utils/envelope-download';
|
||||
import { sortFieldsByPosition, validateFieldsInserted } from '@documenso/lib/utils/fields';
|
||||
import { dynamicActivate } from '@documenso/lib/utils/i18n';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import type {
|
||||
|
|
@ -210,7 +210,7 @@ export const EmbedDirectTemplateClientPage = ({
|
|||
return;
|
||||
}
|
||||
|
||||
const { success: isEmailValid } = z.string().email().safeParse(email);
|
||||
const { success: isEmailValid } = zEmail().safeParse(email);
|
||||
|
||||
if (!isEmailValid) {
|
||||
setEmailError(_(msg`A valid email is required`));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
DEFAULT_DOCUMENT_EMAIL_SETTINGS,
|
||||
ZDocumentEmailSettingsSchema,
|
||||
} from '@documenso/lib/types/document-email';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { DocumentEmailCheckboxes } from '@documenso/ui/components/document/document-email-checkboxes';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
|
@ -33,7 +34,7 @@ import {
|
|||
|
||||
const ZEmailPreferencesFormSchema = z.object({
|
||||
emailId: z.string().nullable(),
|
||||
emailReplyTo: z.string().email().nullable(),
|
||||
emailReplyTo: zEmail().nullable(),
|
||||
// emailReplyToName: z.string(),
|
||||
emailDocumentSettings: ZDocumentEmailSettingsSchema.nullable(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useNavigate } from 'react-router';
|
|||
import { z } from 'zod';
|
||||
|
||||
import { authClient } from '@documenso/auth/client';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
|
|
@ -21,7 +22,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
|||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
export const ZForgotPasswordFormSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
});
|
||||
|
||||
export type TForgotPasswordFormSchema = z.infer<typeof ZForgotPasswordFormSchema>;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { useForm } from 'react-hook-form';
|
|||
import { z } from 'zod';
|
||||
|
||||
import { authClient } from '@documenso/auth/client';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
|
|
@ -20,7 +21,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
|||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
export const ZSendConfirmationEmailFormSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
});
|
||||
|
||||
export type TSendConfirmationEmailFormSchema = z.infer<typeof ZSendConfirmationEmailFormSchema>;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { z } from 'zod';
|
|||
import { authClient } from '@documenso/auth/client';
|
||||
import { AuthenticationErrorCode } from '@documenso/auth/server/lib/errors/error-codes';
|
||||
import { AppError } from '@documenso/lib/errors/app-error';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { ZCurrentPasswordSchema } from '@documenso/trpc/server/auth-router/schema';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
|
|
@ -58,7 +59,7 @@ const handleFallbackErrorMessages = (code: string) => {
|
|||
const LOGIN_REDIRECT_PATH = '/';
|
||||
|
||||
export const ZSignInFormSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
password: ZCurrentPasswordSchema,
|
||||
totpCode: z.string().trim().optional(),
|
||||
backupCode: z.string().trim().optional(),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import communityCardsImage from '@documenso/assets/images/community-cards.png';
|
|||
import { authClient } from '@documenso/auth/client';
|
||||
import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { ZPasswordSchema } from '@documenso/trpc/server/auth-router/schema';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
|
@ -39,7 +40,7 @@ export const ZSignUpFormSchema = z
|
|||
.string()
|
||||
.trim()
|
||||
.min(1, { message: msg`Please enter a valid name.`.id }),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
password: ZPasswordSchema,
|
||||
signature: z.string().min(1, { message: msg`We need your signature to sign documents`.id }),
|
||||
})
|
||||
|
|
|
|||
45
apps/remix/app/components/general/admin-details.tsx
Normal file
45
apps/remix/app/components/general/admin-details.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import type { ReactNode } from 'react';
|
||||
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
|
||||
export type DetailsCardProps = {
|
||||
label: ReactNode;
|
||||
action?: ReactNode;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const DetailsCard = ({ label, action, children }: DetailsCardProps) => {
|
||||
return (
|
||||
<div className="rounded-md border bg-muted/30 px-3 py-2">
|
||||
<div className="flex min-h-9 items-center justify-between gap-3">
|
||||
<span className="text-muted-foreground">{label}</span>
|
||||
{action ?? null}
|
||||
</div>
|
||||
<div className="mt-2 min-h-9">{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export type DetailsValueProps = {
|
||||
children: ReactNode;
|
||||
isMono?: boolean;
|
||||
isSelectable?: boolean;
|
||||
};
|
||||
|
||||
export const DetailsValue = ({
|
||||
children,
|
||||
isMono = true,
|
||||
isSelectable = false,
|
||||
}: DetailsValueProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex min-h-10 items-center break-all rounded-md bg-muted px-3 py-2 text-xs text-muted-foreground',
|
||||
isMono && 'font-mono',
|
||||
isSelectable && 'select-all',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import type { OrganisationGlobalSettings, TeamGlobalSettings } from '@prisma/client';
|
||||
|
||||
import { DOCUMENT_VISIBILITY } from '@documenso/lib/constants/document-visibility';
|
||||
import {
|
||||
type TDocumentEmailSettings,
|
||||
ZDocumentEmailSettingsSchema,
|
||||
} from '@documenso/lib/types/document-email';
|
||||
|
||||
import { DetailsCard, DetailsValue } from '~/components/general/admin-details';
|
||||
|
||||
const EMAIL_SETTINGS_LABELS: Record<keyof TDocumentEmailSettings, MessageDescriptor> = {
|
||||
recipientSigningRequest: msg`Recipient signing request`,
|
||||
recipientRemoved: msg`Recipient removed`,
|
||||
recipientSigned: msg`Recipient signed`,
|
||||
documentPending: msg`Document pending`,
|
||||
documentCompleted: msg`Document completed`,
|
||||
documentDeleted: msg`Document deleted`,
|
||||
ownerDocumentCompleted: msg`Owner document completed`,
|
||||
ownerRecipientExpired: msg`Owner recipient expired`,
|
||||
ownerDocumentCreated: msg`Owner document created`,
|
||||
};
|
||||
|
||||
const emailSettingsKeys = Object.keys(EMAIL_SETTINGS_LABELS) as (keyof TDocumentEmailSettings)[];
|
||||
|
||||
type AdminGlobalSettingsSectionProps = {
|
||||
settings: TeamGlobalSettings | OrganisationGlobalSettings | null;
|
||||
isTeam?: boolean;
|
||||
};
|
||||
|
||||
export const AdminGlobalSettingsSection = ({
|
||||
settings,
|
||||
isTeam = false,
|
||||
}: AdminGlobalSettingsSectionProps) => {
|
||||
const { _ } = useLingui();
|
||||
const notSetLabel = isTeam ? <Trans>Inherited</Trans> : <Trans>Not set</Trans>;
|
||||
|
||||
if (!settings) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const textValue = (value: string | null | undefined) => {
|
||||
if (value === null || value === undefined) {
|
||||
return notSetLabel;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
const brandingTextValue = (value: string | null | undefined) => {
|
||||
if (value === null || value === undefined || value.trim() === '') {
|
||||
return notSetLabel;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
const booleanValue = (value: boolean | null | undefined) => {
|
||||
if (value === null || value === undefined) {
|
||||
return notSetLabel;
|
||||
}
|
||||
|
||||
return value ? <Trans>Enabled</Trans> : <Trans>Disabled</Trans>;
|
||||
};
|
||||
|
||||
const parsedEmailSettings = ZDocumentEmailSettingsSchema.safeParse(
|
||||
settings.emailDocumentSettings,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-3 text-sm sm:grid-cols-2 lg:grid-cols-3">
|
||||
<DetailsCard label={<Trans>Document visibility</Trans>}>
|
||||
<DetailsValue>
|
||||
{settings.documentVisibility != null
|
||||
? _(DOCUMENT_VISIBILITY[settings.documentVisibility].value)
|
||||
: notSetLabel}
|
||||
</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Document language</Trans>}>
|
||||
<DetailsValue>{textValue(settings.documentLanguage)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Document timezone</Trans>}>
|
||||
<DetailsValue>{textValue(settings.documentTimezone)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Date format</Trans>}>
|
||||
<DetailsValue>{textValue(settings.documentDateFormat)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Include sender details</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.includeSenderDetails)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Include signing certificate</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.includeSigningCertificate)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Include audit log</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.includeAuditLog)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Delegate document ownership</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.delegateDocumentOwnership)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Typed signature</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.typedSignatureEnabled)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Upload signature</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.uploadSignatureEnabled)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Draw signature</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.drawSignatureEnabled)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Branding</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.brandingEnabled)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Branding logo</Trans>}>
|
||||
<DetailsValue>{brandingTextValue(settings.brandingLogo)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Branding URL</Trans>}>
|
||||
<DetailsValue>{brandingTextValue(settings.brandingUrl)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Branding company details</Trans>}>
|
||||
<DetailsValue>{brandingTextValue(settings.brandingCompanyDetails)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Email reply-to</Trans>}>
|
||||
<DetailsValue>{textValue(settings.emailReplyTo)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
{isTeam && parsedEmailSettings.success && (
|
||||
<DetailsCard label={<Trans>Email document settings</Trans>}>
|
||||
<div className="mt-1 space-y-1 pb-2 pr-3 text-xs">
|
||||
{emailSettingsKeys.map((key) => (
|
||||
<div key={key} className="flex items-center justify-between gap-2">
|
||||
<span className="text-muted-foreground">{_(EMAIL_SETTINGS_LABELS[key])}</span>
|
||||
<span>
|
||||
{parsedEmailSettings.data[key] ? <Trans>On</Trans> : <Trans>Off</Trans>}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DetailsCard>
|
||||
)}
|
||||
|
||||
<DetailsCard label={<Trans>AI features</Trans>}>
|
||||
<DetailsValue>{booleanValue(settings.aiFeaturesEnabled)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@ import { z } from 'zod';
|
|||
import { authClient } from '@documenso/auth/client';
|
||||
import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics';
|
||||
import { AppError } from '@documenso/lib/errors/app-error';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { ZPasswordSchema } from '@documenso/trpc/server/auth-router/schema';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
|
|
@ -37,7 +38,7 @@ export const ZClaimAccountFormSchema = z
|
|||
.string()
|
||||
.trim()
|
||||
.min(1, { message: msg`Please enter a valid name.`.id }),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
password: ZPasswordSchema,
|
||||
})
|
||||
.refine(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { z } from 'zod';
|
|||
|
||||
import { useOptionalSession } from '@documenso/lib/client-only/providers/session';
|
||||
import type { TTemplate } from '@documenso/lib/types/template';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import {
|
||||
DocumentReadOnlyFields,
|
||||
mapFieldsWithRecipients,
|
||||
|
|
@ -33,7 +34,7 @@ import { useStep } from '@documenso/ui/primitives/stepper';
|
|||
import { useRequiredDocumentSigningAuthContext } from '~/components/general/document-signing/document-signing-auth-provider';
|
||||
|
||||
const ZDirectTemplateConfigureFormSchema = z.object({
|
||||
email: z.string().email('Email is invalid'),
|
||||
email: zEmail('Email is invalid'),
|
||||
});
|
||||
|
||||
export type TDirectTemplateConfigureFormSchema = z.infer<typeof ZDirectTemplateConfigureFormSchema>;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ export const DocumentSigningAuthProvider = ({
|
|||
|
||||
if (
|
||||
derivedRecipientActionAuth.includes(DocumentAuth.ACCOUNT) &&
|
||||
user?.email == recipient.email
|
||||
user?.email === recipient.email
|
||||
) {
|
||||
return {
|
||||
type: DocumentAuth.ACCOUNT,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
ZDocumentAccessAuthSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { fieldsContainUnsignedRequiredField } from '@documenso/lib/utils/advanced-fields-helpers';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
|
|
@ -68,7 +69,7 @@ export type DocumentSigningCompleteDialogProps = {
|
|||
|
||||
const ZNextSignerFormSchema = z.object({
|
||||
name: z.string().min(1, 'Name is required'),
|
||||
email: z.string().email('Invalid email address'),
|
||||
email: zEmail('Invalid email address'),
|
||||
accessAuthOptions: ZDocumentAccessAuthSchema.optional(),
|
||||
});
|
||||
|
||||
|
|
@ -76,7 +77,7 @@ type TNextSignerFormSchema = z.infer<typeof ZNextSignerFormSchema>;
|
|||
|
||||
const ZDirectRecipientFormSchema = z.object({
|
||||
name: z.string(),
|
||||
email: z.string().email('Invalid email address'),
|
||||
email: zEmail('Invalid email address'),
|
||||
});
|
||||
|
||||
type TDirectRecipientFormSchema = z.infer<typeof ZDirectRecipientFormSchema>;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@ import {
|
|||
RecipientRole,
|
||||
SigningStatus,
|
||||
} from '@prisma/client';
|
||||
import { DateTime } from 'luxon';
|
||||
import { prop, sortBy } from 'remeda';
|
||||
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||
import { isBase64Image } from '@documenso/lib/constants/signatures';
|
||||
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
|
||||
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
|
||||
import type { EnvelopeForSigningResponse } from '@documenso/lib/server-only/envelope/get-envelope-for-recipient-signing';
|
||||
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
|
||||
|
|
@ -83,6 +86,54 @@ export interface EnvelopeSigningProviderProps {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject prefilled date fields for the current recipient.
|
||||
*
|
||||
* The dates are filled in correctly when the recipient "completes" the document.
|
||||
*/
|
||||
const prefillDateFields = (data: EnvelopeForSigningResponse): EnvelopeForSigningResponse => {
|
||||
const { timezone, dateFormat } = data.envelope.documentMeta;
|
||||
|
||||
const formattedDate = DateTime.now()
|
||||
.setZone(timezone ?? DEFAULT_DOCUMENT_TIME_ZONE)
|
||||
.toFormat(dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT);
|
||||
|
||||
const prefillField = <
|
||||
T extends { type: FieldType; inserted: boolean; customText: string; fieldMeta: unknown },
|
||||
>(
|
||||
field: T,
|
||||
): T => {
|
||||
if (field.type !== FieldType.DATE || field.inserted) {
|
||||
return field;
|
||||
}
|
||||
|
||||
return {
|
||||
...field,
|
||||
customText: formattedDate,
|
||||
inserted: true,
|
||||
fieldMeta: {
|
||||
...(typeof field.fieldMeta === 'object' ? field.fieldMeta : {}),
|
||||
readOnly: true,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
...data,
|
||||
envelope: {
|
||||
...data.envelope,
|
||||
recipients: data.envelope.recipients.map((recipient) => ({
|
||||
...recipient,
|
||||
fields: recipient.fields.map(prefillField),
|
||||
})),
|
||||
},
|
||||
recipient: {
|
||||
...data.recipient,
|
||||
fields: data.recipient.fields.map(prefillField),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const EnvelopeSigningProvider = ({
|
||||
fullName: initialFullName,
|
||||
email: initialEmail,
|
||||
|
|
@ -90,7 +141,7 @@ export const EnvelopeSigningProvider = ({
|
|||
envelopeData: initialEnvelopeData,
|
||||
children,
|
||||
}: EnvelopeSigningProviderProps) => {
|
||||
const [envelopeData, setEnvelopeData] = useState(initialEnvelopeData);
|
||||
const [envelopeData, setEnvelopeData] = useState(() => prefillDateFields(initialEnvelopeData));
|
||||
|
||||
const { envelope, recipient } = envelopeData;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { DocumentStatus } from '@prisma/client';
|
||||
import { DocumentStatus, EnvelopeType } from '@prisma/client';
|
||||
import {
|
||||
Copy,
|
||||
Download,
|
||||
Edit,
|
||||
FileOutputIcon,
|
||||
Loader,
|
||||
MoreHorizontal,
|
||||
Pencil,
|
||||
ScrollTextIcon,
|
||||
Share,
|
||||
Trash2,
|
||||
|
|
@ -18,8 +19,12 @@ import { Link, useNavigate } from 'react-router';
|
|||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
import type { TEnvelope } from '@documenso/lib/types/envelope';
|
||||
import { isDocumentCompleted } from '@documenso/lib/utils/document';
|
||||
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
|
||||
import {
|
||||
getEnvelopeItemPermissions,
|
||||
mapSecondaryIdToDocumentId,
|
||||
} from '@documenso/lib/utils/envelope';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
|
@ -28,12 +33,13 @@ import {
|
|||
DropdownMenuLabel,
|
||||
DropdownMenuTrigger,
|
||||
} from '@documenso/ui/primitives/dropdown-menu';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { DocumentDeleteDialog } from '~/components/dialogs/document-delete-dialog';
|
||||
import { DocumentDuplicateDialog } from '~/components/dialogs/document-duplicate-dialog';
|
||||
import { DocumentResendDialog } from '~/components/dialogs/document-resend-dialog';
|
||||
import { EnvelopeDeleteDialog } from '~/components/dialogs/envelope-delete-dialog';
|
||||
import { EnvelopeDownloadDialog } from '~/components/dialogs/envelope-download-dialog';
|
||||
import { EnvelopeDuplicateDialog } from '~/components/dialogs/envelope-duplicate-dialog';
|
||||
import { EnvelopeRenameDialog } from '~/components/dialogs/envelope-rename-dialog';
|
||||
import { EnvelopeSaveAsTemplateDialog } from '~/components/dialogs/envelope-save-as-template-dialog';
|
||||
import { DocumentRecipientLinkCopyDialog } from '~/components/general/document/document-recipient-link-copy-dialog';
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
|
||||
|
|
@ -43,14 +49,13 @@ export type DocumentPageViewDropdownProps = {
|
|||
|
||||
export const DocumentPageViewDropdown = ({ envelope }: DocumentPageViewDropdownProps) => {
|
||||
const { user } = useSession();
|
||||
const { toast } = useToast();
|
||||
const { _ } = useLingui();
|
||||
|
||||
const navigate = useNavigate();
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
|
||||
const trpcUtils = trpcReact.useUtils();
|
||||
|
||||
const [isRenameDialogOpen, setRenameDialogOpen] = useState(false);
|
||||
|
||||
const recipient = envelope.recipients.find((recipient) => recipient.email === user.email);
|
||||
|
||||
|
|
@ -62,14 +67,16 @@ export const DocumentPageViewDropdown = ({ envelope }: DocumentPageViewDropdownP
|
|||
const isCurrentTeamDocument = team && envelope.teamId === team.id;
|
||||
const canManageDocument = Boolean(isOwner || isCurrentTeamDocument);
|
||||
|
||||
const { canTitleBeChanged } = getEnvelopeItemPermissions(envelope, []);
|
||||
|
||||
const documentsPath = formatDocumentsPath(team.url);
|
||||
|
||||
const nonSignedRecipients = envelope.recipients.filter((item) => item.signingStatus !== 'SIGNED');
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
|
||||
<DropdownMenuTrigger data-testid="document-page-view-action-btn">
|
||||
<MoreHorizontal className="h-5 w-5 text-muted-foreground" />
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent className="w-52" align="end" forceMount>
|
||||
|
|
@ -86,6 +93,13 @@ export const DocumentPageViewDropdown = ({ envelope }: DocumentPageViewDropdownP
|
|||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{canManageDocument && canTitleBeChanged && (
|
||||
<DropdownMenuItem onClick={() => setRenameDialogOpen(true)}>
|
||||
<Pencil className="mr-2 h-4 w-4" />
|
||||
<Trans>Rename</Trans>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<EnvelopeDownloadDialog
|
||||
envelopeId={envelope.id}
|
||||
envelopeStatus={envelope.status}
|
||||
|
|
@ -108,15 +122,49 @@ export const DocumentPageViewDropdown = ({ envelope }: DocumentPageViewDropdownP
|
|||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem onClick={() => setDuplicateDialogOpen(true)}>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</DropdownMenuItem>
|
||||
<EnvelopeDuplicateDialog
|
||||
envelopeId={envelope.id}
|
||||
envelopeType={EnvelopeType.DOCUMENT}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
<DropdownMenuItem onClick={() => setDeleteDialogOpen(true)} disabled={isDeleted}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
<Trans>Delete</Trans>
|
||||
</DropdownMenuItem>
|
||||
<EnvelopeSaveAsTemplateDialog
|
||||
envelopeId={envelope.id}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<FileOutputIcon className="mr-2 h-4 w-4" />
|
||||
<Trans>Save as Template</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
<EnvelopeDeleteDialog
|
||||
id={envelope.id}
|
||||
type={EnvelopeType.DOCUMENT}
|
||||
status={envelope.status}
|
||||
title={envelope.title}
|
||||
canManageDocument={canManageDocument}
|
||||
onDelete={() => {
|
||||
void navigate(documentsPath);
|
||||
}}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild disabled={isDeleted} onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
<Trans>Delete</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
<DropdownMenuLabel>
|
||||
<Trans>Share</Trans>
|
||||
|
|
@ -159,26 +207,15 @@ export const DocumentPageViewDropdown = ({ envelope }: DocumentPageViewDropdownP
|
|||
/>
|
||||
</DropdownMenuContent>
|
||||
|
||||
<DocumentDeleteDialog
|
||||
id={mapSecondaryIdToDocumentId(envelope.secondaryId)}
|
||||
status={envelope.status}
|
||||
documentTitle={envelope.title}
|
||||
open={isDeleteDialogOpen}
|
||||
canManageDocument={canManageDocument}
|
||||
onOpenChange={setDeleteDialogOpen}
|
||||
onDelete={() => {
|
||||
void navigate(documentsPath);
|
||||
<EnvelopeRenameDialog
|
||||
id={envelope.id}
|
||||
initialTitle={envelope.title}
|
||||
open={isRenameDialogOpen}
|
||||
onOpenChange={setRenameDialogOpen}
|
||||
onSuccess={async () => {
|
||||
await trpcUtils.envelope.get.invalidate();
|
||||
}}
|
||||
/>
|
||||
|
||||
{isDuplicateDialogOpen && (
|
||||
<DocumentDuplicateDialog
|
||||
id={envelope.id}
|
||||
token={recipient?.token}
|
||||
open={isDuplicateDialogOpen}
|
||||
onOpenChange={setDuplicateDialogOpen}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -337,32 +337,42 @@ export const EnvelopeEditorFieldsPage = () => {
|
|||
</h3>
|
||||
|
||||
<div className="space-y-2 rounded-md border border-border bg-muted/50 p-3 text-sm text-foreground">
|
||||
{selectedField.id && (
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Field ID:</Trans>
|
||||
</span>{' '}
|
||||
{selectedField.id}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Recipient ID:</Trans>
|
||||
</span>{' '}
|
||||
{selectedField.recipientId}
|
||||
</p>
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Pos X:</Trans>
|
||||
</span>
|
||||
|
||||
</span>{' '}
|
||||
{selectedField.positionX.toFixed(2)}
|
||||
</p>
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Pos Y:</Trans>
|
||||
</span>
|
||||
|
||||
</span>{' '}
|
||||
{selectedField.positionY.toFixed(2)}
|
||||
</p>
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Width:</Trans>
|
||||
</span>
|
||||
|
||||
</span>{' '}
|
||||
{selectedField.width.toFixed(2)}
|
||||
</p>
|
||||
<p>
|
||||
<span className="min-w-12 text-muted-foreground">
|
||||
<Trans>Height:</Trans>
|
||||
</span>
|
||||
|
||||
</span>{' '}
|
||||
{selectedField.height.toFixed(2)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import {
|
|||
canAccessTeamDocument,
|
||||
extractTeamSignatureSettings,
|
||||
} from '@documenso/lib/utils/teams';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { DocumentEmailCheckboxes } from '@documenso/ui/components/document/document-email-checkboxes';
|
||||
import {
|
||||
|
|
@ -138,10 +139,7 @@ export const ZAddSettingsFormSchema = z.object({
|
|||
.optional()
|
||||
.default('en'),
|
||||
emailId: z.string().nullable(),
|
||||
emailReplyTo: z.preprocess(
|
||||
(val) => (val === '' ? undefined : val),
|
||||
z.string().email().optional(),
|
||||
),
|
||||
emailReplyTo: z.preprocess((val) => (val === '' ? undefined : val), zEmail().optional()),
|
||||
emailSettings: ZDocumentEmailSettingsSchema,
|
||||
signatureTypes: z.array(z.nativeEnum(DocumentSignatureType)).min(1, {
|
||||
message: msg`At least one signature type must be enabled`.id,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
CopyPlusIcon,
|
||||
DownloadCloudIcon,
|
||||
EyeIcon,
|
||||
FileOutputIcon,
|
||||
LinkIcon,
|
||||
type LucideIcon,
|
||||
MousePointerIcon,
|
||||
|
|
@ -35,6 +36,7 @@ import { EnvelopeDistributeDialog } from '~/components/dialogs/envelope-distribu
|
|||
import { EnvelopeDownloadDialog } from '~/components/dialogs/envelope-download-dialog';
|
||||
import { EnvelopeDuplicateDialog } from '~/components/dialogs/envelope-duplicate-dialog';
|
||||
import { EnvelopeRedistributeDialog } from '~/components/dialogs/envelope-redistribute-dialog';
|
||||
import { EnvelopeSaveAsTemplateDialog } from '~/components/dialogs/envelope-save-as-template-dialog';
|
||||
import { TemplateDirectLinkDialog } from '~/components/dialogs/template-direct-link-dialog';
|
||||
import { EnvelopeEditorSettingsDialog } from '~/components/general/envelope-editor/envelope-editor-settings-dialog';
|
||||
|
||||
|
|
@ -101,6 +103,7 @@ export const EnvelopeEditor = () => {
|
|||
allowDistributing,
|
||||
allowDirectLink,
|
||||
allowDuplication,
|
||||
allowSaveAsTemplate,
|
||||
allowDownloadPDF,
|
||||
allowDeletion,
|
||||
},
|
||||
|
|
@ -466,6 +469,28 @@ export const EnvelopeEditor = () => {
|
|||
/>
|
||||
)}
|
||||
|
||||
{allowSaveAsTemplate && isDocument && (
|
||||
<EnvelopeSaveAsTemplateDialog
|
||||
envelopeId={envelope.id}
|
||||
trigger={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full justify-start"
|
||||
title={t(msg`Save as Template`)}
|
||||
>
|
||||
<FileOutputIcon className="h-4 w-4" />
|
||||
|
||||
{!minimizeLeftSidebar && (
|
||||
<span className="ml-2">
|
||||
<Trans>Save as Template</Trans>
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{allowDownloadPDF && (
|
||||
<EnvelopeDownloadDialog
|
||||
envelopeId={envelope.id}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { useForm } from 'react-hook-form';
|
|||
import { useRevalidator } from 'react-router';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table';
|
||||
|
|
@ -46,7 +47,7 @@ const RECIPIENT_ROLE_LABELS: Record<RecipientRole, string> = {
|
|||
|
||||
const ZAdminUpdateRecipientFormSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email(),
|
||||
email: zEmail(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { match } from 'ts-pattern';
|
|||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
import type { TDocumentMany as TDocumentRow } from '@documenso/lib/types/document';
|
||||
import { isDocumentCompleted } from '@documenso/lib/utils/document';
|
||||
import { findRecipientByEmail } from '@documenso/lib/utils/recipients';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
||||
|
|
@ -23,7 +24,11 @@ export const DocumentsTableActionButton = ({ row }: DocumentsTableActionButtonPr
|
|||
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const recipient = row.recipients.find((recipient) => recipient.email === user.email);
|
||||
const recipient = findRecipientByEmail({
|
||||
recipients: row.recipients,
|
||||
userEmail: user.email,
|
||||
teamEmail: team.teamEmail?.email,
|
||||
});
|
||||
|
||||
const isOwner = row.user.id === user.id;
|
||||
const isRecipient = !!recipient;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ import { useState } from 'react';
|
|||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { DocumentStatus, RecipientRole } from '@prisma/client';
|
||||
import { DocumentStatus, EnvelopeType, RecipientRole } from '@prisma/client';
|
||||
import {
|
||||
CheckCircle,
|
||||
Copy,
|
||||
Download,
|
||||
Edit,
|
||||
EyeIcon,
|
||||
FileOutputIcon,
|
||||
FolderInput,
|
||||
Loader,
|
||||
MoreHorizontal,
|
||||
|
|
@ -22,7 +23,10 @@ import { Link } from 'react-router';
|
|||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
import type { TDocumentMany as TDocumentRow } from '@documenso/lib/types/document';
|
||||
import { isDocumentCompleted } from '@documenso/lib/utils/document';
|
||||
import { getEnvelopeItemPermissions } from '@documenso/lib/utils/envelope';
|
||||
import { findRecipientByEmail } from '@documenso/lib/utils/recipients';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
|
@ -32,13 +36,15 @@ import {
|
|||
DropdownMenuTrigger,
|
||||
} from '@documenso/ui/primitives/dropdown-menu';
|
||||
|
||||
import { DocumentDeleteDialog } from '~/components/dialogs/document-delete-dialog';
|
||||
import { DocumentDuplicateDialog } from '~/components/dialogs/document-duplicate-dialog';
|
||||
import { DocumentResendDialog } from '~/components/dialogs/document-resend-dialog';
|
||||
import { EnvelopeDeleteDialog } from '~/components/dialogs/envelope-delete-dialog';
|
||||
import { EnvelopeDuplicateDialog } from '~/components/dialogs/envelope-duplicate-dialog';
|
||||
import { EnvelopeSaveAsTemplateDialog } from '~/components/dialogs/envelope-save-as-template-dialog';
|
||||
import { DocumentRecipientLinkCopyDialog } from '~/components/general/document/document-recipient-link-copy-dialog';
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
|
||||
import { EnvelopeDownloadDialog } from '../dialogs/envelope-download-dialog';
|
||||
import { EnvelopeRenameDialog } from '../dialogs/envelope-rename-dialog';
|
||||
|
||||
export type DocumentsTableActionDropdownProps = {
|
||||
row: TDocumentRow;
|
||||
|
|
@ -53,11 +59,15 @@ export const DocumentsTableActionDropdown = ({
|
|||
const team = useCurrentTeam();
|
||||
|
||||
const { _ } = useLingui();
|
||||
const trpcUtils = trpcReact.useUtils();
|
||||
|
||||
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
|
||||
const [isRenameDialogOpen, setRenameDialogOpen] = useState(false);
|
||||
|
||||
const recipient = row.recipients.find((recipient) => recipient.email === user.email);
|
||||
const recipient = findRecipientByEmail({
|
||||
recipients: row.recipients,
|
||||
userEmail: user.email,
|
||||
teamEmail: team.teamEmail?.email,
|
||||
});
|
||||
|
||||
const isOwner = row.user.id === user.id;
|
||||
// const isRecipient = !!recipient;
|
||||
|
|
@ -68,6 +78,16 @@ export const DocumentsTableActionDropdown = ({
|
|||
const isCurrentTeamDocument = team && row.team?.url === team.url;
|
||||
const canManageDocument = Boolean(isOwner || isCurrentTeamDocument);
|
||||
|
||||
const { canTitleBeChanged } = getEnvelopeItemPermissions(
|
||||
{
|
||||
completedAt: row.completedAt,
|
||||
deletedAt: row.deletedAt,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
status: row.status,
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const documentsPath = formatDocumentsPath(team.url);
|
||||
const formatPath = `${documentsPath}/${row.envelopeId}/edit`;
|
||||
|
||||
|
|
@ -76,7 +96,7 @@ export const DocumentsTableActionDropdown = ({
|
|||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger data-testid="document-table-action-btn">
|
||||
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
|
||||
<MoreHorizontal className="h-5 w-5 text-muted-foreground" />
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent className="w-52" align="start" forceMount>
|
||||
|
|
@ -121,6 +141,13 @@ export const DocumentsTableActionDropdown = ({
|
|||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
||||
{canManageDocument && canTitleBeChanged && (
|
||||
<DropdownMenuItem onClick={() => setRenameDialogOpen(true)}>
|
||||
<Pencil className="mr-2 h-4 w-4" />
|
||||
<Trans>Rename</Trans>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<EnvelopeDownloadDialog
|
||||
envelopeId={row.envelopeId}
|
||||
envelopeStatus={row.status}
|
||||
|
|
@ -135,10 +162,30 @@ export const DocumentsTableActionDropdown = ({
|
|||
}
|
||||
/>
|
||||
|
||||
<DropdownMenuItem onClick={() => setDuplicateDialogOpen(true)}>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</DropdownMenuItem>
|
||||
<EnvelopeDuplicateDialog
|
||||
envelopeId={row.envelopeId}
|
||||
envelopeType={EnvelopeType.DOCUMENT}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
<EnvelopeSaveAsTemplateDialog
|
||||
envelopeId={row.envelopeId}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<FileOutputIcon className="mr-2 h-4 w-4" />
|
||||
<Trans>Save as Template</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
{onMoveDocument && canManageDocument && (
|
||||
<DropdownMenuItem onClick={onMoveDocument} onSelect={(e) => e.preventDefault()}>
|
||||
|
|
@ -153,10 +200,21 @@ export const DocumentsTableActionDropdown = ({
|
|||
Void
|
||||
</DropdownMenuItem> */}
|
||||
|
||||
<DropdownMenuItem onClick={() => setDeleteDialogOpen(true)}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
{canManageDocument ? _(msg`Delete`) : _(msg`Hide`)}
|
||||
</DropdownMenuItem>
|
||||
<EnvelopeDeleteDialog
|
||||
id={row.envelopeId}
|
||||
type={EnvelopeType.DOCUMENT}
|
||||
status={row.status}
|
||||
title={row.title}
|
||||
canManageDocument={canManageDocument}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
{canManageDocument ? _(msg`Delete`) : _(msg`Hide`)}
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
|
||||
<DropdownMenuLabel>
|
||||
<Trans>Share</Trans>
|
||||
|
|
@ -192,20 +250,14 @@ export const DocumentsTableActionDropdown = ({
|
|||
/>
|
||||
</DropdownMenuContent>
|
||||
|
||||
<DocumentDeleteDialog
|
||||
id={row.id}
|
||||
status={row.status}
|
||||
documentTitle={row.title}
|
||||
open={isDeleteDialogOpen}
|
||||
onOpenChange={setDeleteDialogOpen}
|
||||
canManageDocument={canManageDocument}
|
||||
/>
|
||||
|
||||
<DocumentDuplicateDialog
|
||||
<EnvelopeRenameDialog
|
||||
id={row.envelopeId}
|
||||
token={recipient?.token}
|
||||
open={isDuplicateDialogOpen}
|
||||
onOpenChange={setDuplicateDialogOpen}
|
||||
initialTitle={row.title}
|
||||
open={isRenameDialogOpen}
|
||||
onOpenChange={setRenameDialogOpen}
|
||||
onSuccess={async () => {
|
||||
await trpcUtils.document.findDocumentsInternal.invalidate();
|
||||
}}
|
||||
/>
|
||||
</DropdownMenu>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@ import { match } from 'ts-pattern';
|
|||
|
||||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
import type { TDocumentMany as TDocumentRow } from '@documenso/lib/types/document';
|
||||
import { findRecipientByEmail } from '@documenso/lib/utils/recipients';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
|
||||
export type DataTableTitleProps = {
|
||||
row: TDocumentRow;
|
||||
teamUrl: string;
|
||||
|
|
@ -12,8 +15,13 @@ export type DataTableTitleProps = {
|
|||
|
||||
export const DataTableTitle = ({ row, teamUrl }: DataTableTitleProps) => {
|
||||
const { user } = useSession();
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const recipient = row.recipients.find((recipient) => recipient.email === user.email);
|
||||
const recipient = findRecipientByEmail({
|
||||
recipients: row.recipients,
|
||||
userEmail: user.email,
|
||||
teamEmail: team.teamEmail?.email,
|
||||
});
|
||||
|
||||
const isOwner = row.user.id === user.id;
|
||||
const isRecipient = !!recipient;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { match } from 'ts-pattern';
|
|||
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
|
||||
import { useSession } from '@documenso/lib/client-only/providers/session';
|
||||
import { isDocumentCompleted } from '@documenso/lib/utils/document';
|
||||
import { findRecipientByEmail } from '@documenso/lib/utils/recipients';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import type { TFindDocumentsResponse } from '@documenso/trpc/server/document-router/find-documents.types';
|
||||
import { Checkbox } from '@documenso/ui/primitives/checkbox';
|
||||
|
|
@ -91,7 +92,13 @@ export const DocumentsTable = ({
|
|||
},
|
||||
{
|
||||
header: _(msg`Title`),
|
||||
cell: ({ row }) => <DataTableTitle row={row.original} teamUrl={team?.url} />,
|
||||
cell: ({ row }) => (
|
||||
<DataTableTitle
|
||||
row={row.original}
|
||||
teamUrl={team?.url}
|
||||
teamEmail={team?.teamEmail?.email}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'sender',
|
||||
|
|
@ -213,12 +220,17 @@ export const DocumentsTable = ({
|
|||
type DataTableTitleProps = {
|
||||
row: DocumentsTableRow;
|
||||
teamUrl: string;
|
||||
teamEmail?: string;
|
||||
};
|
||||
|
||||
const DataTableTitle = ({ row, teamUrl }: DataTableTitleProps) => {
|
||||
const DataTableTitle = ({ row, teamUrl, teamEmail }: DataTableTitleProps) => {
|
||||
const { user } = useSession();
|
||||
|
||||
const recipient = row.recipients.find((recipient) => recipient.email === user.email);
|
||||
const recipient = findRecipientByEmail({
|
||||
recipients: row.recipients,
|
||||
userEmail: user.email,
|
||||
teamEmail,
|
||||
});
|
||||
|
||||
const isOwner = row.user.id === user.id;
|
||||
const isRecipient = !!recipient;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,14 @@ export const OrganisationInsightsTable = ({
|
|||
{
|
||||
header: _(msg`Team Name`),
|
||||
accessorKey: 'name',
|
||||
cell: ({ row }) => <span className="block max-w-full truncate">{row.getValue('name')}</span>,
|
||||
cell: ({ row }) => (
|
||||
<Link
|
||||
className="block max-w-full truncate hover:underline"
|
||||
to={`/admin/teams/${row.original.id}`}
|
||||
>
|
||||
{row.getValue('name')}
|
||||
</Link>
|
||||
),
|
||||
size: 240,
|
||||
},
|
||||
{
|
||||
|
|
@ -276,12 +283,12 @@ const SummaryCard = ({
|
|||
value: number;
|
||||
subtitle?: string;
|
||||
}) => (
|
||||
<div className="bg-card flex items-start gap-x-2 rounded-lg border px-4 py-3">
|
||||
<Icon className="text-muted-foreground h-4 w-4 items-start" />
|
||||
<div className="flex items-start gap-x-2 rounded-lg border bg-card px-4 py-3">
|
||||
<Icon className="h-4 w-4 items-start text-muted-foreground" />
|
||||
<div className="-mt-0.5 space-y-2">
|
||||
<p className="text-muted-foreground text-sm font-medium">{title}</p>
|
||||
<p className="text-sm font-medium text-muted-foreground">{title}</p>
|
||||
<p className="text-2xl font-bold">{value}</p>
|
||||
{subtitle && <p className="text-muted-foreground text-xs">{subtitle}</p>}
|
||||
{subtitle && <p className="text-xs text-muted-foreground">{subtitle}</p>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export const OrganisationTeamsTable = () => {
|
|||
avatarClass="h-12 w-12"
|
||||
avatarFallback={row.original.name.slice(0, 1).toUpperCase()}
|
||||
primaryText={
|
||||
<span className="text-foreground/80 font-semibold">{row.original.name}</span>
|
||||
<span className="font-semibold text-foreground/80">{row.original.name}</span>
|
||||
}
|
||||
secondaryText={`${NEXT_PUBLIC_WEBAPP_URL()}/t/${row.original.url}`}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,25 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import type { Recipient, TemplateDirectLink } from '@prisma/client';
|
||||
import { Copy, Edit, FolderIcon, MoreHorizontal, Share2Icon, Trash2, Upload } from 'lucide-react';
|
||||
import {
|
||||
DocumentStatus,
|
||||
EnvelopeType,
|
||||
type Recipient,
|
||||
type TemplateDirectLink,
|
||||
} from '@prisma/client';
|
||||
import {
|
||||
Copy,
|
||||
Edit,
|
||||
FolderIcon,
|
||||
MoreHorizontal,
|
||||
Pencil,
|
||||
Share2Icon,
|
||||
Trash2,
|
||||
Upload,
|
||||
} from 'lucide-react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { trpc as trpcReact } from '@documenso/trpc/react';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
|
|
@ -13,10 +28,11 @@ import {
|
|||
DropdownMenuTrigger,
|
||||
} from '@documenso/ui/primitives/dropdown-menu';
|
||||
|
||||
import { EnvelopeDeleteDialog } from '../dialogs/envelope-delete-dialog';
|
||||
import { EnvelopeDuplicateDialog } from '../dialogs/envelope-duplicate-dialog';
|
||||
import { EnvelopeRenameDialog } from '../dialogs/envelope-rename-dialog';
|
||||
import { TemplateBulkSendDialog } from '../dialogs/template-bulk-send-dialog';
|
||||
import { TemplateDeleteDialog } from '../dialogs/template-delete-dialog';
|
||||
import { TemplateDirectLinkDialog } from '../dialogs/template-direct-link-dialog';
|
||||
import { TemplateDuplicateDialog } from '../dialogs/template-duplicate-dialog';
|
||||
import { TemplateMoveToFolderDialog } from '../dialogs/template-move-to-folder-dialog';
|
||||
|
||||
export type TemplatesTableActionDropdownProps = {
|
||||
|
|
@ -41,8 +57,9 @@ export const TemplatesTableActionDropdown = ({
|
|||
teamId,
|
||||
onDelete,
|
||||
}: TemplatesTableActionDropdownProps) => {
|
||||
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
|
||||
const trpcUtils = trpcReact.useUtils();
|
||||
|
||||
const [isRenameDialogOpen, setRenameDialogOpen] = useState(false);
|
||||
const [isMoveToFolderDialogOpen, setMoveToFolderDialogOpen] = useState(false);
|
||||
|
||||
const isTeamTemplate = row.teamId === teamId;
|
||||
|
|
@ -66,10 +83,27 @@ export const TemplatesTableActionDropdown = ({
|
|||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem disabled={!canMutate} onClick={() => setDuplicateDialogOpen(true)}>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</DropdownMenuItem>
|
||||
{canMutate && (
|
||||
<DropdownMenuItem onClick={() => setRenameDialogOpen(true)}>
|
||||
<Pencil className="mr-2 h-4 w-4" />
|
||||
<Trans>Rename</Trans>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{canMutate && (
|
||||
<EnvelopeDuplicateDialog
|
||||
envelopeId={row.envelopeId}
|
||||
envelopeType={EnvelopeType.TEMPLATE}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Copy className="mr-2 h-4 w-4" />
|
||||
<Trans>Duplicate</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{canMutate && (
|
||||
<TemplateDirectLinkDialog
|
||||
|
|
@ -106,25 +140,26 @@ export const TemplatesTableActionDropdown = ({
|
|||
/>
|
||||
)}
|
||||
|
||||
<DropdownMenuItem disabled={!canMutate} onClick={() => setDeleteDialogOpen(true)}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
<Trans>Delete</Trans>
|
||||
</DropdownMenuItem>
|
||||
{canMutate && (
|
||||
<EnvelopeDeleteDialog
|
||||
id={row.envelopeId}
|
||||
type={EnvelopeType.TEMPLATE}
|
||||
status={DocumentStatus.DRAFT}
|
||||
title={row.title}
|
||||
canManageDocument={canMutate}
|
||||
onDelete={onDelete}
|
||||
trigger={
|
||||
<DropdownMenuItem asChild onSelect={(e) => e.preventDefault()}>
|
||||
<div>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
<Trans>Delete</Trans>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
|
||||
<TemplateDuplicateDialog
|
||||
id={row.id}
|
||||
open={isDuplicateDialogOpen}
|
||||
onOpenChange={setDuplicateDialogOpen}
|
||||
/>
|
||||
|
||||
<TemplateDeleteDialog
|
||||
id={row.id}
|
||||
open={isDeleteDialogOpen}
|
||||
onOpenChange={setDeleteDialogOpen}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
|
||||
<TemplateMoveToFolderDialog
|
||||
templateId={row.id}
|
||||
templateTitle={row.title}
|
||||
|
|
@ -132,6 +167,17 @@ export const TemplatesTableActionDropdown = ({
|
|||
onOpenChange={setMoveToFolderDialogOpen}
|
||||
currentFolderId={row.folderId}
|
||||
/>
|
||||
|
||||
<EnvelopeRenameDialog
|
||||
id={row.envelopeId}
|
||||
initialTitle={row.title}
|
||||
open={isRenameDialogOpen}
|
||||
onOpenChange={setRenameDialogOpen}
|
||||
envelopeType="template"
|
||||
onSuccess={async () => {
|
||||
await trpcUtils.template.findTemplates.invalidate();
|
||||
}}
|
||||
/>
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ export default function OrganisationInsights({ loaderData }: Route.ComponentProp
|
|||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<OrganisationInsightsTable
|
||||
insights={insights}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ import { useMemo } from 'react';
|
|||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { OrganisationMemberRole } from '@prisma/client';
|
||||
import { ExternalLinkIcon, InfoIcon, Loader } from 'lucide-react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Link, useNavigate } from 'react-router';
|
||||
import { match } from 'ts-pattern';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
|
|
@ -15,9 +16,16 @@ import { AppError } from '@documenso/lib/errors/app-error';
|
|||
import { LicenseClient } from '@documenso/lib/server-only/license/license-client';
|
||||
import type { TLicenseClaim } from '@documenso/lib/types/license';
|
||||
import { SUBSCRIPTION_CLAIM_FEATURE_FLAGS } from '@documenso/lib/types/subscription';
|
||||
import { getHighestOrganisationRoleInGroup } from '@documenso/lib/utils/organisations';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import type { TGetAdminOrganisationResponse } from '@documenso/trpc/server/admin-router/get-admin-organisation.types';
|
||||
import { ZUpdateAdminOrganisationRequestSchema } from '@documenso/trpc/server/admin-router/update-admin-organisation.types';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from '@documenso/ui/primitives/accordion';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
|
||||
import { Badge } from '@documenso/ui/primitives/badge';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
|
@ -37,6 +45,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitive
|
|||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { AdminOrganisationMemberUpdateDialog } from '~/components/dialogs/admin-organisation-member-update-dialog';
|
||||
import { DetailsCard, DetailsValue } from '~/components/general/admin-details';
|
||||
import { AdminGlobalSettingsSection } from '~/components/general/admin-global-settings-section';
|
||||
import { GenericErrorLayout } from '~/components/general/generic-error-layout';
|
||||
import { SettingsHeader } from '~/components/general/settings-header';
|
||||
|
||||
|
|
@ -56,7 +66,7 @@ export default function OrganisationGroupSettingsPage({
|
|||
}: Route.ComponentProps) {
|
||||
const { licenseFlags } = loaderData;
|
||||
|
||||
const { t, i18n } = useLingui();
|
||||
const { i18n, t } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -92,35 +102,102 @@ export default function OrganisationGroupSettingsPage({
|
|||
{
|
||||
header: t`Team`,
|
||||
accessorKey: 'name',
|
||||
cell: ({ row }) => (
|
||||
<Link className="font-medium hover:underline" to={`/admin/teams/${row.original.id}`}>
|
||||
{row.original.name}
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t`Team ID`,
|
||||
accessorKey: 'id',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-xs text-muted-foreground">{row.original.id}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t`Team url`,
|
||||
accessorKey: 'url',
|
||||
cell: ({ row }) => <span className="font-mono text-xs">{row.original.url}</span>,
|
||||
},
|
||||
{
|
||||
header: t`Created`,
|
||||
accessorKey: 'createdAt',
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<span className="whitespace-nowrap font-mono text-xs text-muted-foreground">
|
||||
{i18n.date(row.original.createdAt)}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
] satisfies DataTableColumnDef<TGetAdminOrganisationResponse['teams'][number]>[];
|
||||
}, [t]);
|
||||
}, [i18n, t]);
|
||||
|
||||
const organisationMembersColumns = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
header: t`Member`,
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<Link to={`/admin/users/${row.original.user.id}`}>{row.original.user.name}</Link>
|
||||
{row.original.user.id === organisation?.ownerUserId && (
|
||||
<Badge>
|
||||
<Trans>Owner</Trans>
|
||||
</Badge>
|
||||
<div className="space-y-1">
|
||||
<Link
|
||||
className="font-medium hover:underline"
|
||||
to={`/admin/users/${row.original.user.id}`}
|
||||
>
|
||||
{row.original.user.name ?? row.original.user.email}
|
||||
</Link>
|
||||
{row.original.user.name && (
|
||||
<div className="font-mono text-xs text-muted-foreground">
|
||||
{row.original.user.email}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t`Email`,
|
||||
header: t`User ID`,
|
||||
accessorKey: 'userId',
|
||||
cell: ({ row }) => (
|
||||
<Link to={`/admin/users/${row.original.user.id}`}>{row.original.user.email}</Link>
|
||||
<span className="font-mono text-xs text-muted-foreground">{row.original.userId}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t`Role`,
|
||||
cell: ({ row }) => {
|
||||
if (!organisation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isOwner = row.original.userId === organisation.ownerUserId;
|
||||
|
||||
if (isOwner) {
|
||||
return <Badge>{t`Owner`}</Badge>;
|
||||
}
|
||||
|
||||
const highestRole = getHighestOrganisationRoleInGroup(
|
||||
row.original.organisationGroupMembers.map((ogm) => ogm.group),
|
||||
);
|
||||
|
||||
const roleLabel = match(highestRole)
|
||||
.with(OrganisationMemberRole.ADMIN, () => t`Admin`)
|
||||
.with(OrganisationMemberRole.MANAGER, () => t`Manager`)
|
||||
.with(OrganisationMemberRole.MEMBER, () => t`Member`)
|
||||
.exhaustive();
|
||||
|
||||
return <Badge variant="secondary">{roleLabel}</Badge>;
|
||||
},
|
||||
},
|
||||
{
|
||||
header: t`Joined`,
|
||||
accessorKey: 'createdAt',
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<span className="whitespace-nowrap font-mono text-xs text-muted-foreground">
|
||||
{i18n.date(row.original.createdAt)}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: t`Actions`,
|
||||
cell: ({ row }) => {
|
||||
|
|
@ -143,7 +220,7 @@ export default function OrganisationGroupSettingsPage({
|
|||
},
|
||||
},
|
||||
] satisfies DataTableColumnDef<TGetAdminOrganisationResponse['members'][number]>[];
|
||||
}, [organisation, t]);
|
||||
}, [organisation, i18n, t]);
|
||||
|
||||
if (isLoadingOrganisation) {
|
||||
return (
|
||||
|
|
@ -191,6 +268,61 @@ export default function OrganisationGroupSettingsPage({
|
|||
|
||||
<GenericOrganisationAdminForm organisation={organisation} />
|
||||
|
||||
<div className="mt-6 rounded-lg border p-4">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Organisation usage</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<Trans>Current usage against organisation limits.</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 gap-3 text-sm sm:grid-cols-2">
|
||||
<DetailsCard label={<Trans>Members</Trans>}>
|
||||
<DetailsValue>
|
||||
{organisation.members.length} /{' '}
|
||||
{organisation.organisationClaim.memberCount === 0
|
||||
? t`Unlimited`
|
||||
: organisation.organisationClaim.memberCount}
|
||||
</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Teams</Trans>}>
|
||||
<DetailsValue>
|
||||
{organisation.teams.length} /{' '}
|
||||
{organisation.organisationClaim.teamCount === 0
|
||||
? t`Unlimited`
|
||||
: organisation.organisationClaim.teamCount}
|
||||
</DetailsValue>
|
||||
</DetailsCard>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 rounded-lg border p-4">
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="global-settings" className="border-b-0">
|
||||
<AccordionTrigger className="py-0">
|
||||
<div className="text-left">
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Global Settings</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm font-normal text-muted-foreground">
|
||||
<Trans>Default settings applied to this organisation.</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="mt-4">
|
||||
<AdminGlobalSettingsSection settings={organisation.organisationGlobalSettings} />
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
|
||||
<SettingsHeader
|
||||
title={t`Manage subscription`}
|
||||
subtitle={t`Manage the ${organisation.name} organisation subscription`}
|
||||
|
|
|
|||
317
apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
Normal file
317
apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
import { useMemo } from 'react';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { CopyIcon } from 'lucide-react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { ORGANISATION_MEMBER_ROLE_MAP } from '@documenso/lib/constants/organisations-translations';
|
||||
import { TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams-translations';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import type { TGetAdminTeamResponse } from '@documenso/trpc/server/admin-router/get-admin-team.types';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from '@documenso/ui/primitives/accordion';
|
||||
import { Badge } from '@documenso/ui/primitives/badge';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { DataTable, type DataTableColumnDef } from '@documenso/ui/primitives/data-table';
|
||||
import { SpinnerBox } from '@documenso/ui/primitives/spinner';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { DetailsCard, DetailsValue } from '~/components/general/admin-details';
|
||||
import { AdminGlobalSettingsSection } from '~/components/general/admin-global-settings-section';
|
||||
import { GenericErrorLayout } from '~/components/general/generic-error-layout';
|
||||
import { SettingsHeader } from '~/components/general/settings-header';
|
||||
|
||||
import type { Route } from './+types/teams.$id';
|
||||
|
||||
export default function AdminTeamPage({ params }: Route.ComponentProps) {
|
||||
const { _, i18n } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const teamId = Number(params.id);
|
||||
|
||||
const { data: team, isLoading } = trpc.admin.team.get.useQuery(
|
||||
{
|
||||
teamId,
|
||||
},
|
||||
{
|
||||
enabled: Number.isFinite(teamId) && teamId > 0,
|
||||
},
|
||||
);
|
||||
|
||||
const onCopyToClipboard = async (text: string) => {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
toast({
|
||||
title: _(msg`Copied to clipboard`),
|
||||
});
|
||||
};
|
||||
|
||||
const teamMembersColumns = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
header: _(msg`Member`),
|
||||
cell: ({ row }) => (
|
||||
<div className="space-y-1">
|
||||
<Link
|
||||
className="font-medium hover:underline"
|
||||
to={`/admin/users/${row.original.user.id}`}
|
||||
>
|
||||
{row.original.user.name ?? row.original.user.email}
|
||||
</Link>
|
||||
{row.original.user.name && (
|
||||
<div className="font-mono text-xs text-muted-foreground">
|
||||
{row.original.user.email}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: _(msg`User ID`),
|
||||
accessorKey: 'userId',
|
||||
},
|
||||
{
|
||||
header: _(msg`Team role`),
|
||||
accessorKey: 'teamRole',
|
||||
cell: ({ row }) => (
|
||||
<Badge variant="secondary">{_(TEAM_MEMBER_ROLE_MAP[row.original.teamRole])}</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: _(msg`Organisation role`),
|
||||
accessorKey: 'organisationRole',
|
||||
cell: ({ row }) => {
|
||||
const isOwner = row.original.userId === team?.organisation.ownerUserId;
|
||||
|
||||
if (isOwner) {
|
||||
return <Badge>{_(msg`Owner`)}</Badge>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Badge variant="secondary">
|
||||
{_(ORGANISATION_MEMBER_ROLE_MAP[row.original.organisationRole])}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: _(msg`Joined`),
|
||||
accessorKey: 'createdAt',
|
||||
cell: ({ row }) => i18n.date(row.original.createdAt),
|
||||
},
|
||||
] satisfies DataTableColumnDef<TGetAdminTeamResponse['teamMembers'][number]>[];
|
||||
}, [team, _, i18n]);
|
||||
|
||||
const pendingInvitesColumns = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
header: _(msg`Email`),
|
||||
accessorKey: 'email',
|
||||
},
|
||||
{
|
||||
header: _(msg`Role`),
|
||||
accessorKey: 'organisationRole',
|
||||
cell: ({ row }) => _(ORGANISATION_MEMBER_ROLE_MAP[row.original.organisationRole]),
|
||||
},
|
||||
{
|
||||
header: _(msg`Invited`),
|
||||
accessorKey: 'createdAt',
|
||||
cell: ({ row }) => i18n.date(row.original.createdAt),
|
||||
},
|
||||
] satisfies DataTableColumnDef<TGetAdminTeamResponse['pendingInvites'][number]>[];
|
||||
}, [_, i18n]);
|
||||
|
||||
if (!Number.isFinite(teamId) || teamId <= 0) {
|
||||
return (
|
||||
<GenericErrorLayout
|
||||
errorCode={404}
|
||||
errorCodeMap={{
|
||||
404: {
|
||||
heading: msg`Team not found`,
|
||||
subHeading: msg`404 Team not found`,
|
||||
message: msg`The team you are looking for may have been removed, renamed or may have never existed.`,
|
||||
},
|
||||
}}
|
||||
primaryButton={
|
||||
<Button asChild>
|
||||
<Link to={`/admin/organisations`}>
|
||||
<Trans>Go back</Trans>
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
secondaryButton={null}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <SpinnerBox className="py-32" />;
|
||||
}
|
||||
|
||||
if (!team) {
|
||||
return (
|
||||
<GenericErrorLayout
|
||||
errorCode={404}
|
||||
errorCodeMap={{
|
||||
404: {
|
||||
heading: msg`Team not found`,
|
||||
subHeading: msg`404 Team not found`,
|
||||
message: msg`The team you are looking for may have been removed, renamed or may have never existed.`,
|
||||
},
|
||||
}}
|
||||
primaryButton={
|
||||
<Button asChild>
|
||||
<Link to={`/admin/organisations`}>
|
||||
<Trans>Go back</Trans>
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
secondaryButton={null}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SettingsHeader title={_(msg`Manage team`)} subtitle={_(msg`Manage the ${team.name} team`)}>
|
||||
<Button variant="outline" asChild>
|
||||
<Link to={`/admin/organisations/${team.organisation.id}`}>
|
||||
<Trans>Manage organisation</Trans>
|
||||
</Link>
|
||||
</Button>
|
||||
</SettingsHeader>
|
||||
|
||||
<div className="mt-8 rounded-lg border p-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Team details</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<Trans>Key identifiers and relationships for this team.</Trans>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 gap-3 text-sm sm:grid-cols-2 lg:grid-cols-3">
|
||||
<DetailsCard
|
||||
label={<Trans>Team ID</Trans>}
|
||||
action={
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-8 w-8 shrink-0 p-0"
|
||||
onClick={() => void onCopyToClipboard(String(team.id))}
|
||||
title={_(msg`Copy team ID`)}
|
||||
>
|
||||
<CopyIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<DetailsValue isSelectable>{team.id}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Team URL</Trans>}>
|
||||
<DetailsValue isSelectable>{team.url}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Created</Trans>}>
|
||||
<DetailsValue>{i18n.date(team.createdAt)}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Members</Trans>}>
|
||||
<DetailsValue>{team.memberCount}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard
|
||||
label={<Trans>Organisation ID</Trans>}
|
||||
action={
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-8 w-8 shrink-0 p-0"
|
||||
onClick={() => void onCopyToClipboard(team.organisation.id)}
|
||||
title={_(msg`Copy organisation ID`)}
|
||||
>
|
||||
<CopyIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<DetailsValue isSelectable>{team.organisation.id}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
{team.teamEmail && (
|
||||
<>
|
||||
<DetailsCard label={<Trans>Team email</Trans>}>
|
||||
<DetailsValue isSelectable>{team.teamEmail.email}</DetailsValue>
|
||||
</DetailsCard>
|
||||
|
||||
<DetailsCard label={<Trans>Team email name</Trans>}>
|
||||
<DetailsValue>{team.teamEmail.name}</DetailsValue>
|
||||
</DetailsCard>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{team.teamGlobalSettings && (
|
||||
<div className="mt-8 rounded-lg border p-4">
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="global-settings" className="border-b-0">
|
||||
<AccordionTrigger className="py-0">
|
||||
<div className="text-left">
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Global Settings</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm font-normal text-muted-foreground">
|
||||
<Trans>
|
||||
Default settings applied to this team. Inherited values come from the
|
||||
organisation.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="mt-4">
|
||||
<AdminGlobalSettingsSection settings={team.teamGlobalSettings} isTeam />
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-8">
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Team Members</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<Trans>Members that currently belong to this team.</Trans>
|
||||
</p>
|
||||
|
||||
<div className="mt-4">
|
||||
<DataTable columns={teamMembersColumns} data={team.teamMembers} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Pending Organisation Invites</Trans>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<Trans>Organisation-level pending invites for this team's parent organisation.</Trans>
|
||||
</p>
|
||||
|
||||
<div className="mt-4">
|
||||
<DataTable columns={pendingInvitesColumns} data={team.pendingInvites} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -70,6 +70,7 @@ export default function EmbedPlaygroundPage() {
|
|||
allowDistributing: false,
|
||||
allowDirectLink: false,
|
||||
allowDuplication: false,
|
||||
allowSaveAsTemplate: false,
|
||||
allowDownloadPDF: false,
|
||||
allowDeletion: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ export default function AuthoringLayout() {
|
|||
createdAt: new Date(),
|
||||
avatarImageId: null,
|
||||
organisationId: '',
|
||||
teamEmail: null,
|
||||
currentTeamRole: TeamMemberRole.MEMBER,
|
||||
preferences: {
|
||||
aiFeaturesEnabled: preferences.aiFeaturesEnabled,
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ app.route('/api/ai', aiRoute);
|
|||
// API servers.
|
||||
app.route('/api/v1', tsRestHonoApp);
|
||||
app.use('/api/jobs/*', jobsClient.getApiHandler());
|
||||
|
||||
app.use('/api/trpc/*', trpcRateLimitMiddleware);
|
||||
app.use('/api/trpc/*', reactRouterTrpcServer);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { defaultOptions as devServerDefaults } from '@hono/vite-dev-server';
|
||||
import { lingui } from '@lingui/vite-plugin';
|
||||
import { reactRouter } from '@react-router/dev/vite';
|
||||
import autoprefixer from 'autoprefixer';
|
||||
|
|
@ -46,6 +47,18 @@ export default defineConfig({
|
|||
tsconfigPaths(),
|
||||
serverAdapter({
|
||||
entry: 'server/router.ts',
|
||||
exclude: [
|
||||
// Spread the defaults but replace the /.css$/ rule so that Bull
|
||||
// Board's static CSS at /api/jobs/board/static/** passes through to Hono.
|
||||
...devServerDefaults.exclude.map((pattern) =>
|
||||
pattern instanceof RegExp && pattern.source === '.*\\.css$'
|
||||
? /^(?!\/api\/jobs\/board\/).*\.css$/
|
||||
: pattern,
|
||||
),
|
||||
'/assets/**',
|
||||
'/src/app/**',
|
||||
/\?(?:inline|url|no-inline|raw|import(?:&(?:inline|url|no-inline|raw)?)?)$/,
|
||||
],
|
||||
}),
|
||||
],
|
||||
ssr: {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,14 @@ services:
|
|||
- 2500:2500
|
||||
- 1100:1100
|
||||
|
||||
redis:
|
||||
image: redis:8-alpine
|
||||
container_name: redis
|
||||
ports:
|
||||
- 63790:6379
|
||||
volumes:
|
||||
- redis:/data
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
container_name: minio
|
||||
|
|
@ -42,4 +50,5 @@ services:
|
|||
|
||||
volumes:
|
||||
minio:
|
||||
redis:
|
||||
documenso_database:
|
||||
|
|
|
|||
391
package-lock.json
generated
391
package-lock.json
generated
|
|
@ -580,20 +580,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"apps/docs/node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"apps/docs/node_modules/undici-types": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
||||
|
|
@ -2650,6 +2636,41 @@
|
|||
"integrity": "sha512-ckS3+vyJb5qGpEYv/s1OebUHDi/xSNtfgw1wqKZo7MR9F2z+qXr0q5XagafAG/9O0QPVIUfST0smluYSTpYFkg==",
|
||||
"license": "(Apache-2.0 AND BSD-3-Clause)"
|
||||
},
|
||||
"node_modules/@bull-board/api": {
|
||||
"version": "6.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@bull-board/api/-/api-6.20.6.tgz",
|
||||
"integrity": "sha512-B/9OlKWJ/He421Lyuc7htMpKN4R8hcNu5uoIRiyh9y9J0kMOfxfs82GKXdfR9R0595LvAcCOSvjn8EtWHXesTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"redis-info": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@bull-board/ui": "6.20.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@bull-board/hono": {
|
||||
"version": "6.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@bull-board/hono/-/hono-6.20.6.tgz",
|
||||
"integrity": "sha512-l2yGfL6gT2Z5sVP12YRw4kmyNISA2NqR+5h5QaSHQfHAv62hnARPPrvzOCjPBXpzIWwBQwjhnYQXv89QoyoQiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bull-board/api": "6.20.6",
|
||||
"@bull-board/ui": "6.20.6",
|
||||
"ejs": "^3.1.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hono": "^4"
|
||||
}
|
||||
},
|
||||
"node_modules/@bull-board/ui": {
|
||||
"version": "6.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@bull-board/ui/-/ui-6.20.6.tgz",
|
||||
"integrity": "sha512-nEXRgMHHd48ssINgvDqT7b4p/+57XRf3CUcTGQ7UIJb4F7n/kRRj8+ZQvQmMFsYGdNmbNU2eNheQ05vXSYiqdQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bull-board/api": "6.20.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@cantoo/pdf-lib": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@cantoo/pdf-lib/-/pdf-lib-2.5.3.tgz",
|
||||
|
|
@ -4470,6 +4491,12 @@
|
|||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ioredis/commands": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz",
|
||||
"integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
|
|
@ -5076,6 +5103,84 @@
|
|||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
||||
"integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
|
||||
"integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
|
||||
"integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
|
||||
"integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
|
||||
"integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
|
||||
"integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@napi-rs/canvas": {
|
||||
"version": "0.1.83",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.83.tgz",
|
||||
|
|
@ -17981,6 +18086,12 @@
|
|||
"astring": "bin/astring"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
|
|
@ -18434,6 +18545,46 @@
|
|||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bullmq": {
|
||||
"version": "5.72.0",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.72.0.tgz",
|
||||
"integrity": "sha512-1Wmfym7bC8BFxDjKcF4iZNZmqXYo0rgPFlxfi8ET3AaP/vOY/MY33iWsWqAKwe8v/QO/8osipjwTAcFB7egINA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cron-parser": "4.9.0",
|
||||
"ioredis": "5.10.1",
|
||||
"msgpackr": "1.11.5",
|
||||
"node-abort-controller": "3.1.1",
|
||||
"semver": "7.7.4",
|
||||
"tslib": "2.8.1",
|
||||
"uuid": "11.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bullmq/node_modules/cron-parser": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz",
|
||||
"integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"luxon": "^3.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bullmq/node_modules/uuid": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
|
|
@ -19040,6 +19191,15 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cluster-key-slot": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cmdk": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.1.tgz",
|
||||
|
|
@ -20699,6 +20859,15 @@
|
|||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/denque": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
|
||||
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
|
|
@ -21021,6 +21190,21 @@
|
|||
"fast-check": "^3.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
"bin": {
|
||||
"ejs": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.259",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.259.tgz",
|
||||
|
|
@ -22263,6 +22447,36 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
|
||||
"integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"minimatch": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
|
||||
"integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
|
|
@ -23901,6 +24115,30 @@
|
|||
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ioredis": {
|
||||
"version": "5.10.1",
|
||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.10.1.tgz",
|
||||
"integrity": "sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ioredis/commands": "1.5.1",
|
||||
"cluster-key-slot": "^1.1.0",
|
||||
"debug": "^4.3.4",
|
||||
"denque": "^2.1.0",
|
||||
"lodash.defaults": "^4.2.0",
|
||||
"lodash.isarguments": "^3.1.0",
|
||||
"redis-errors": "^1.2.0",
|
||||
"redis-parser": "^3.0.0",
|
||||
"standard-as-callback": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.22.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ioredis"
|
||||
}
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
|
|
@ -24214,6 +24452,23 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/jake": {
|
||||
"version": "10.9.4",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
|
||||
"integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"async": "^3.2.6",
|
||||
"filelist": "^1.0.4",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"jake": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-get-type": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
|
||||
|
|
@ -25159,6 +25414,12 @@
|
|||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.defaults": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.get": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
|
|
@ -25166,6 +25427,12 @@
|
|||
"deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isarguments": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
|
||||
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
|
|
@ -26969,6 +27236,37 @@
|
|||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/msgpackr": {
|
||||
"version": "1.11.5",
|
||||
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.5.tgz",
|
||||
"integrity": "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==",
|
||||
"license": "MIT",
|
||||
"optionalDependencies": {
|
||||
"msgpackr-extract": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/msgpackr-extract": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
|
||||
"integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"node-gyp-build-optional-packages": "5.2.2"
|
||||
},
|
||||
"bin": {
|
||||
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
|
||||
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
|
||||
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
|
||||
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
|
||||
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
|
||||
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
|
|
@ -27142,6 +27440,12 @@
|
|||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abort-controller": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
|
||||
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
|
|
@ -27200,6 +27504,21 @@
|
|||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp-build-optional-packages": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
|
||||
"integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"node-gyp-build-optional-packages": "bin.js",
|
||||
"node-gyp-build-optional-packages-optional": "optional.js",
|
||||
"node-gyp-build-optional-packages-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-better-parser": {
|
||||
"version": "1.5.8",
|
||||
"resolved": "https://registry.npmjs.org/node-html-better-parser/-/node-html-better-parser-1.5.8.tgz",
|
||||
|
|
@ -29740,6 +30059,36 @@
|
|||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-errors": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
|
||||
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-info": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-info/-/redis-info-3.1.0.tgz",
|
||||
"integrity": "sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-parser": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
|
||||
"integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"redis-errors": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||
|
|
@ -31003,6 +31352,12 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/standard-as-callback": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/start-server-and-test": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.1.3.tgz",
|
||||
|
|
@ -33554,7 +33909,8 @@
|
|||
"@types/node": "^20",
|
||||
"@types/pngjs": "^6.0.5",
|
||||
"pixelmatch": "^7.1.0",
|
||||
"pngjs": "^7.0.0"
|
||||
"pngjs": "^7.0.0",
|
||||
"tsx": "^4.20.6"
|
||||
}
|
||||
},
|
||||
"packages/app-tests/node_modules/@playwright/test": {
|
||||
|
|
@ -33928,6 +34284,9 @@
|
|||
"@aws-sdk/cloudfront-signer": "^3.998.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.998.0",
|
||||
"@aws-sdk/signature-v4-crt": "^3.998.0",
|
||||
"@bull-board/api": "^6.20.6",
|
||||
"@bull-board/hono": "^6.20.6",
|
||||
"@bull-board/ui": "^6.20.6",
|
||||
"@documenso/assets": "*",
|
||||
"@documenso/email": "*",
|
||||
"@documenso/prisma": "*",
|
||||
|
|
@ -33946,8 +34305,10 @@
|
|||
"@team-plain/typescript-sdk": "^5.11.0",
|
||||
"@vvo/tzdb": "^6.196.0",
|
||||
"ai": "^5.0.104",
|
||||
"bullmq": "^5.71.1",
|
||||
"csv-parse": "^6.1.0",
|
||||
"inngest": "^3.45.1",
|
||||
"ioredis": "^5.10.1",
|
||||
"jose": "^6.1.2",
|
||||
"konva": "^10.0.9",
|
||||
"kysely": "0.28.8",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZEnvelopeAttachmentTypeSchema } from '@documenso/lib/types/envelope-attachment';
|
||||
import { ZFieldMetaPrefillFieldsSchema, ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ export const ZCreateDocumentMutationSchema = z.object({
|
|||
recipients: z.array(
|
||||
z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
}),
|
||||
|
|
@ -224,7 +225,7 @@ export const ZCreateDocumentMutationResponseSchema = z.object({
|
|||
z.object({
|
||||
recipientId: z.number(),
|
||||
name: z.string(),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
|
@ -244,7 +245,7 @@ export const ZCreateDocumentFromTemplateMutationSchema = z.object({
|
|||
recipients: z.array(
|
||||
z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
}),
|
||||
|
|
@ -299,7 +300,7 @@ export const ZCreateDocumentFromTemplateMutationResponseSchema = z.object({
|
|||
z.object({
|
||||
recipientId: z.number(),
|
||||
name: z.string(),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
|
@ -326,7 +327,7 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
|
|||
.array(
|
||||
z.object({
|
||||
id: z.number(),
|
||||
email: z.string().email(),
|
||||
email: zEmail(),
|
||||
name: z.string().optional(),
|
||||
signingOrder: z.number().optional(),
|
||||
}),
|
||||
|
|
@ -386,7 +387,7 @@ export const ZGenerateDocumentFromTemplateMutationResponseSchema = z.object({
|
|||
z.object({
|
||||
recipientId: z.number(),
|
||||
name: z.string(),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
|
@ -402,7 +403,7 @@ export type TGenerateDocumentFromTemplateMutationResponseSchema = z.infer<
|
|||
|
||||
export const ZCreateRecipientMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
authOptions: z
|
||||
|
|
@ -437,7 +438,7 @@ export const ZSuccessfulRecipientResponseSchema = z.object({
|
|||
// !: This handles the fact that we have null documentId's for templates
|
||||
// !: while we won't need the default we must add it to satisfy typescript
|
||||
documentId: z.number().nullish().default(-1),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
name: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
|
@ -576,7 +577,7 @@ export const ZRecipientSchema = z.object({
|
|||
id: z.number(),
|
||||
documentId: z.number().nullish(),
|
||||
templateId: z.number().nullish(),
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
name: z.string(),
|
||||
token: z.string(),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ test.describe('document editor', () => {
|
|||
await page.getByRole('button', { name: 'Duplicate' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Envelope Duplicated');
|
||||
await expectToastTextToBeVisible(page, 'Document Duplicated');
|
||||
|
||||
// The page should have navigated to the new document's edit page.
|
||||
await expect(page).toHaveURL(/\/documents\/.*\/edit/);
|
||||
|
|
@ -422,7 +422,7 @@ test.describe('template editor', () => {
|
|||
await page.getByRole('button', { name: 'Duplicate' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Envelope Duplicated');
|
||||
await expectToastTextToBeVisible(page, 'Template Duplicated');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,495 @@
|
|||
import { type Page, expect, test } from '@playwright/test';
|
||||
import { EnvelopeType, FieldType, RecipientRole } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
import {
|
||||
clickAddMyselfButton,
|
||||
clickEnvelopeEditorStep,
|
||||
getRecipientEmailInputs,
|
||||
openDocumentEnvelopeEditor,
|
||||
} from '../fixtures/envelope-editor';
|
||||
import { expectToastTextToBeVisible } from '../fixtures/generic';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const V2_API_BASE_URL = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
const examplePdfBuffer = fs.readFileSync(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
|
||||
/**
|
||||
* Place a field on the PDF canvas in the envelope editor.
|
||||
*/
|
||||
const placeFieldOnPdf = async (
|
||||
root: Page,
|
||||
fieldName: 'Signature' | 'Text',
|
||||
position: { x: number; y: number },
|
||||
) => {
|
||||
await root.getByRole('button', { name: fieldName, exact: true }).click();
|
||||
|
||||
const canvas = root.locator('.konva-container canvas').first();
|
||||
await expect(canvas).toBeVisible();
|
||||
await canvas.click({ position });
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a V2 document envelope via the API with a single SIGNER recipient
|
||||
* and a SIGNATURE field, suitable for testing save-as-template with data.
|
||||
*
|
||||
* Returns the envelope ID, user, team, and recipient email.
|
||||
*/
|
||||
const createDocumentWithRecipientAndField = async () => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: `e2e-save-as-template-${Date.now()}`,
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const recipientEmail = `save-template-${Date.now()}@test.documenso.com`;
|
||||
|
||||
// 1. Create envelope with a PDF.
|
||||
const payload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: `E2E Save as Template ${Date.now()}`,
|
||||
} satisfies TCreateEnvelopePayload;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([examplePdfBuffer], 'example.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const createRes = await fetch(`${V2_API_BASE_URL}/envelope/create`, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: formData,
|
||||
});
|
||||
|
||||
expect(createRes.ok).toBeTruthy();
|
||||
const createResponse = (await createRes.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
// 2. Create a SIGNER recipient.
|
||||
const createRecipientsRequest: TCreateEnvelopeRecipientsRequest = {
|
||||
envelopeId: createResponse.id,
|
||||
data: [
|
||||
{
|
||||
email: recipientEmail,
|
||||
name: 'Template Test Signer',
|
||||
role: RecipientRole.SIGNER,
|
||||
accessAuth: [],
|
||||
actionAuth: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const recipientsRes = await fetch(`${V2_API_BASE_URL}/envelope/recipient/create-many`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(createRecipientsRequest),
|
||||
});
|
||||
|
||||
expect(recipientsRes.ok).toBeTruthy();
|
||||
const recipientsResponse = await recipientsRes.json();
|
||||
const recipients = recipientsResponse.data;
|
||||
|
||||
// 3. Get envelope to find the envelope item ID.
|
||||
const getRes = await fetch(`${V2_API_BASE_URL}/envelope/${createResponse.id}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
const envelope = (await getRes.json()) as TGetEnvelopeResponse;
|
||||
const envelopeItem = envelope.envelopeItems[0];
|
||||
|
||||
// 4. Create a SIGNATURE field for the recipient.
|
||||
const createFieldsRequest = {
|
||||
envelopeId: createResponse.id,
|
||||
data: [
|
||||
{
|
||||
recipientId: recipients[0].id,
|
||||
envelopeItemId: envelopeItem.id,
|
||||
type: FieldType.SIGNATURE,
|
||||
page: 1,
|
||||
positionX: 100,
|
||||
positionY: 100,
|
||||
width: 50,
|
||||
height: 50,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const fieldsRes = await fetch(`${V2_API_BASE_URL}/envelope/field/create-many`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(createFieldsRequest),
|
||||
});
|
||||
|
||||
expect(fieldsRes.ok).toBeTruthy();
|
||||
|
||||
return {
|
||||
user,
|
||||
team,
|
||||
envelopeId: createResponse.id,
|
||||
recipientEmail,
|
||||
};
|
||||
};
|
||||
|
||||
test.describe('document editor', () => {
|
||||
test('save document as template from editor sidebar', async ({ page }) => {
|
||||
const surface = await openDocumentEnvelopeEditor(page);
|
||||
|
||||
// Add the current user as a recipient via the UI.
|
||||
await clickAddMyselfButton(surface.root);
|
||||
await expect(getRecipientEmailInputs(surface.root).first()).toHaveValue(surface.userEmail);
|
||||
|
||||
// Navigate to the add fields step and place a signature field.
|
||||
await clickEnvelopeEditorStep(surface.root, 'addFields');
|
||||
await expect(surface.root.locator('.konva-container canvas').first()).toBeVisible();
|
||||
await placeFieldOnPdf(surface.root, 'Signature', { x: 120, y: 140 });
|
||||
|
||||
// Navigate back to the upload step so the sidebar actions are available.
|
||||
await clickEnvelopeEditorStep(surface.root, 'upload');
|
||||
|
||||
// Click the "Save as Template" sidebar action.
|
||||
await page.locator('button[title="Save as Template"]').click();
|
||||
|
||||
// The save as template dialog should appear.
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Both checkboxes should be checked by default.
|
||||
await expect(page.locator('#envelopeIncludeRecipients')).toBeChecked();
|
||||
await expect(page.locator('#envelopeIncludeFields')).toBeChecked();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Verify the new template envelope was created in the database with correct type and secondaryId.
|
||||
const templateEnvelopes = await prisma.envelope.findMany({
|
||||
where: {
|
||||
userId: surface.userId,
|
||||
teamId: surface.teamId,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
include: {
|
||||
recipients: {
|
||||
include: {
|
||||
fields: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(templateEnvelopes.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const createdTemplate = templateEnvelopes.find((e) => e.title.includes('(copy)'));
|
||||
expect(createdTemplate).toBeDefined();
|
||||
|
||||
// CRITICAL: Verify the secondaryId uses the template_ prefix, not document_.
|
||||
// This confirms incrementTemplateId was called, not incrementDocumentId.
|
||||
expect(createdTemplate!.secondaryId).toMatch(/^template_\d+$/);
|
||||
expect(createdTemplate!.type).toBe(EnvelopeType.TEMPLATE);
|
||||
|
||||
// Verify recipients were included.
|
||||
expect(createdTemplate!.recipients.length).toBe(1);
|
||||
expect(createdTemplate!.recipients[0].email).toBe(surface.userEmail);
|
||||
|
||||
// Verify fields were included.
|
||||
expect(createdTemplate!.recipients[0].fields.length).toBe(1);
|
||||
expect(createdTemplate!.recipients[0].fields[0].type).toBe(FieldType.SIGNATURE);
|
||||
});
|
||||
|
||||
test('save document as template without recipients', async ({ page }) => {
|
||||
const { user, team, envelopeId, recipientEmail } = await createDocumentWithRecipientAndField();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents/${envelopeId}/edit`,
|
||||
});
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Documents' })).toBeVisible();
|
||||
|
||||
// Click the "Save as Template" sidebar action.
|
||||
await page.locator('button[title="Save as Template"]').click();
|
||||
|
||||
// The dialog should appear.
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Uncheck "Include Recipients" - "Include Fields" should auto-disable.
|
||||
await page.locator('#envelopeIncludeRecipients').click();
|
||||
await expect(page.locator('#envelopeIncludeRecipients')).not.toBeChecked();
|
||||
await expect(page.locator('#envelopeIncludeFields')).not.toBeChecked();
|
||||
await expect(page.locator('#envelopeIncludeFields')).toBeDisabled();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Verify the template was created without recipients.
|
||||
const templateEnvelopes = await prisma.envelope.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
const createdTemplate = templateEnvelopes.find((e) => e.title.includes('(copy)'));
|
||||
expect(createdTemplate).toBeDefined();
|
||||
|
||||
// CRITICAL: Verify the secondaryId uses the template_ prefix.
|
||||
expect(createdTemplate!.secondaryId).toMatch(/^template_\d+$/);
|
||||
|
||||
// Verify no recipients were included.
|
||||
expect(createdTemplate!.recipients.length).toBe(0);
|
||||
});
|
||||
|
||||
test('save document as template without fields but with recipients', async ({ page }) => {
|
||||
const { user, team, envelopeId, recipientEmail } = await createDocumentWithRecipientAndField();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents/${envelopeId}/edit`,
|
||||
});
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Documents' })).toBeVisible();
|
||||
|
||||
// Click the "Save as Template" sidebar action.
|
||||
await page.locator('button[title="Save as Template"]').click();
|
||||
|
||||
// The dialog should appear.
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Uncheck "Include Fields" but keep "Include Recipients".
|
||||
await page.locator('#envelopeIncludeFields').click();
|
||||
await expect(page.locator('#envelopeIncludeRecipients')).toBeChecked();
|
||||
await expect(page.locator('#envelopeIncludeFields')).not.toBeChecked();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Verify the template was created with recipients but no fields.
|
||||
const templateEnvelopes = await prisma.envelope.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
include: {
|
||||
recipients: {
|
||||
include: {
|
||||
fields: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createdTemplate = templateEnvelopes.find((e) => e.title.includes('(copy)'));
|
||||
expect(createdTemplate).toBeDefined();
|
||||
|
||||
// CRITICAL: Verify the secondaryId uses the template_ prefix.
|
||||
expect(createdTemplate!.secondaryId).toMatch(/^template_\d+$/);
|
||||
|
||||
// Verify recipients were included.
|
||||
expect(createdTemplate!.recipients.length).toBe(1);
|
||||
expect(createdTemplate!.recipients[0].email).toBe(recipientEmail);
|
||||
|
||||
// Verify no fields were included.
|
||||
expect(createdTemplate!.recipients[0].fields.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('documents table', () => {
|
||||
test('save as template from document row dropdown', async ({ page }) => {
|
||||
const { user, team, envelopeId, recipientEmail } = await createDocumentWithRecipientAndField();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
// Wait for the documents table to load.
|
||||
await expect(page.getByRole('heading', { name: 'Documents' })).toBeVisible();
|
||||
|
||||
// Click the actions dropdown for the document row.
|
||||
await page.getByTestId('document-table-action-btn').first().click();
|
||||
|
||||
// Click "Save as Template" in the dropdown.
|
||||
await page.getByRole('menuitem', { name: 'Save as Template' }).click();
|
||||
|
||||
// The dialog should appear.
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Verify the template was created with correct type and secondaryId.
|
||||
const templateEnvelopes = await prisma.envelope.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
include: {
|
||||
recipients: {
|
||||
include: {
|
||||
fields: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createdTemplate = templateEnvelopes.find((e) => e.title.includes('(copy)'));
|
||||
expect(createdTemplate).toBeDefined();
|
||||
|
||||
// CRITICAL: Verify the secondaryId uses the template_ prefix.
|
||||
expect(createdTemplate!.secondaryId).toMatch(/^template_\d+$/);
|
||||
expect(createdTemplate!.type).toBe(EnvelopeType.TEMPLATE);
|
||||
|
||||
// Verify recipients and fields were included (defaults are both checked).
|
||||
expect(createdTemplate!.recipients.length).toBe(1);
|
||||
expect(createdTemplate!.recipients[0].fields.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('document index page', () => {
|
||||
test('save as template from document page dropdown', async ({ page }) => {
|
||||
const { user, team, envelopeId, recipientEmail } = await createDocumentWithRecipientAndField();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents/${envelopeId}`,
|
||||
});
|
||||
|
||||
// Wait for the document page to load.
|
||||
await expect(page.getByRole('heading', { name: /E2E Save as Template/ })).toBeVisible();
|
||||
|
||||
// Click the more actions dropdown trigger.
|
||||
await page.getByTestId('document-page-view-action-btn').click();
|
||||
|
||||
// Click "Save as Template" in the dropdown.
|
||||
await page.getByRole('menuitem', { name: 'Save as Template' }).click();
|
||||
|
||||
// The dialog should appear.
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
|
||||
// Assert toast appears.
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
|
||||
// The page should have navigated to the new template's edit page.
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Verify the template was created with correct type and secondaryId.
|
||||
const templateEnvelopes = await prisma.envelope.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
});
|
||||
|
||||
const createdTemplate = templateEnvelopes.find((e) => e.title.includes('(copy)'));
|
||||
expect(createdTemplate).toBeDefined();
|
||||
|
||||
// CRITICAL: Verify the secondaryId uses the template_ prefix.
|
||||
expect(createdTemplate!.secondaryId).toMatch(/^template_\d+$/);
|
||||
expect(createdTemplate!.type).toBe(EnvelopeType.TEMPLATE);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('legacy ID correctness', () => {
|
||||
test('save as template uses template counter, not document counter', async ({ page }) => {
|
||||
// Record the current counter values before the operation.
|
||||
const [documentCounterBefore, templateCounterBefore] = await Promise.all([
|
||||
prisma.counter.findUnique({ where: { id: 'document' } }),
|
||||
prisma.counter.findUnique({ where: { id: 'template' } }),
|
||||
]);
|
||||
|
||||
const surface = await openDocumentEnvelopeEditor(page);
|
||||
|
||||
// Click the "Save as Template" sidebar action.
|
||||
await page.locator('button[title="Save as Template"]').click();
|
||||
await expect(page.getByRole('heading', { name: 'Save as Template' })).toBeVisible();
|
||||
|
||||
// Click "Save as Template".
|
||||
await page.getByRole('button', { name: 'Save as Template' }).click();
|
||||
await expectToastTextToBeVisible(page, 'Template Created');
|
||||
await expect(page).toHaveURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Record the counter values after the operation.
|
||||
const [documentCounterAfter, templateCounterAfter] = await Promise.all([
|
||||
prisma.counter.findUnique({ where: { id: 'document' } }),
|
||||
prisma.counter.findUnique({ where: { id: 'template' } }),
|
||||
]);
|
||||
|
||||
// The template counter MUST have incremented (at least once - could be more due to
|
||||
// the seedBlankDocument call in openDocumentEnvelopeEditor seeding other templates).
|
||||
expect(templateCounterAfter!.value).toBeGreaterThan(templateCounterBefore!.value);
|
||||
|
||||
// Verify the created template's secondaryId matches the template counter.
|
||||
const createdTemplate = await prisma.envelope.findFirst({
|
||||
where: {
|
||||
userId: surface.userId,
|
||||
teamId: surface.teamId,
|
||||
type: 'TEMPLATE',
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
|
||||
expect(createdTemplate).not.toBeNull();
|
||||
expect(createdTemplate!.secondaryId).toBe(`template_${templateCounterAfter!.value}`);
|
||||
expect(createdTemplate!.secondaryId).not.toMatch(/^document_/);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { createCanvas } from '@napi-rs/canvas';
|
||||
import type { TestInfo } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { DocumentStatus, EnvelopeType } from '@prisma/client';
|
||||
import { DocumentStatus, EnvelopeType, FieldType } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.mjs';
|
||||
|
|
@ -161,7 +161,16 @@ test('field placement visual regression', async ({ page, request }, testInfo) =>
|
|||
const uninsertedFields = await prisma.field.findMany({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
inserted: false,
|
||||
OR: [
|
||||
{
|
||||
inserted: false,
|
||||
},
|
||||
{
|
||||
// Include email fields because they are automatically inserted during envelope distribution.
|
||||
// We need to extract it to override their values for accurate comparison in tests.
|
||||
type: FieldType.EMAIL,
|
||||
},
|
||||
],
|
||||
},
|
||||
include: {
|
||||
envelopeItem: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,264 @@
|
|||
import { expect, test } from '@playwright/test';
|
||||
import { DocumentStatus, FieldType } from '@prisma/client';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { apiSeedPendingDocument } from '../fixtures/api-seeds';
|
||||
|
||||
const PDF_PAGE_SELECTOR = 'img[data-page-number]';
|
||||
|
||||
test.describe('V2 envelope field insertion during signing', () => {
|
||||
test('date fields are auto-inserted when completing a V2 envelope', async ({ page, request }) => {
|
||||
const now = DateTime.now().setZone(DEFAULT_DOCUMENT_TIME_ZONE);
|
||||
|
||||
const { envelope, distributeResult } = await apiSeedPendingDocument(request, {
|
||||
recipients: [{ email: 'signer-date@test.documenso.com', name: 'Date Signer' }],
|
||||
fieldsPerRecipient: [
|
||||
[
|
||||
{ type: FieldType.DATE, page: 1, positionX: 5, positionY: 5, width: 5, height: 5 },
|
||||
{ type: FieldType.SIGNATURE, page: 1, positionX: 5, positionY: 15, width: 5, height: 5 },
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
const { token } = distributeResult.recipients[0];
|
||||
|
||||
await page.goto(`/sign/${token}`);
|
||||
|
||||
// wait for PDF to be visible
|
||||
await expect(page.locator(PDF_PAGE_SELECTOR).first()).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
// Wait for the Konva canvas to be ready.
|
||||
const canvas = page.locator('.konva-container canvas').first();
|
||||
await expect(canvas).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
// DATE is auto-filled, but SIGNATURE still needs manual interaction.
|
||||
await expect(page.getByText('1 Field Remaining').first()).toBeVisible();
|
||||
|
||||
// Set up a signature via the sidebar form.
|
||||
await page.getByTestId('signature-pad-dialog-button').click();
|
||||
await page.getByRole('tab', { name: 'Type' }).click();
|
||||
await page.getByTestId('signature-pad-type-input').fill('Signature');
|
||||
await page.getByRole('button', { name: 'Next' }).click();
|
||||
|
||||
// Click the signature field on the canvas.
|
||||
const canvasBox = await canvas.boundingBox();
|
||||
|
||||
if (!canvasBox) {
|
||||
throw new Error('Canvas bounding box not found');
|
||||
}
|
||||
|
||||
const sigField = envelope.fields.find((f) => f.type === FieldType.SIGNATURE);
|
||||
|
||||
if (!sigField) {
|
||||
throw new Error('Signature field not found');
|
||||
}
|
||||
|
||||
const x =
|
||||
(Number(sigField.positionX) / 100) * canvasBox.width +
|
||||
((Number(sigField.width) / 100) * canvasBox.width) / 2;
|
||||
const y =
|
||||
(Number(sigField.positionY) / 100) * canvasBox.height +
|
||||
((Number(sigField.height) / 100) * canvasBox.height) / 2;
|
||||
|
||||
await canvas.click({ position: { x, y } });
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await expect(page.getByText('0 Fields Remaining').first()).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
await page.getByRole('button', { name: 'Complete' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Are you sure?' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Sign' }).click();
|
||||
|
||||
await page.waitForURL(`/sign/${token}/complete`);
|
||||
await expect(page.getByText('Document Signed')).toBeVisible();
|
||||
|
||||
// Verify the date field was inserted in the database with the correct format.
|
||||
const dateField = await prisma.field.findFirstOrThrow({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
type: FieldType.DATE,
|
||||
},
|
||||
});
|
||||
|
||||
expect(dateField.inserted).toBe(true);
|
||||
expect(dateField.customText).toBeTruthy();
|
||||
|
||||
// Verify the inserted date is close to now (within 2 minutes).
|
||||
const insertedDate = DateTime.fromFormat(dateField.customText, DEFAULT_DOCUMENT_DATE_FORMAT, {
|
||||
zone: DEFAULT_DOCUMENT_TIME_ZONE,
|
||||
});
|
||||
|
||||
expect(insertedDate.isValid).toBe(true);
|
||||
expect(Math.abs(insertedDate.diff(now, 'minutes').minutes)).toBeLessThanOrEqual(2);
|
||||
|
||||
// Verify the document reached COMPLETED status.
|
||||
await expect(async () => {
|
||||
const dbEnvelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: envelope.id },
|
||||
});
|
||||
|
||||
expect(dbEnvelope.status).toBe(DocumentStatus.COMPLETED);
|
||||
}).toPass();
|
||||
});
|
||||
|
||||
test('date and email fields are inserted when completing a V2 envelope with multiple field types', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
const now = DateTime.now().setZone(DEFAULT_DOCUMENT_TIME_ZONE);
|
||||
|
||||
const recipientEmail = 'signer-multi@test.documenso.com';
|
||||
|
||||
const { envelope, distributeResult } = await apiSeedPendingDocument(request, {
|
||||
recipients: [{ email: recipientEmail, name: 'Multi Signer' }],
|
||||
fieldsPerRecipient: [
|
||||
[
|
||||
{ type: FieldType.DATE, page: 1, positionX: 5, positionY: 5, width: 5, height: 5 },
|
||||
{ type: FieldType.EMAIL, page: 1, positionX: 5, positionY: 10, width: 5, height: 5 },
|
||||
{ type: FieldType.NAME, page: 1, positionX: 5, positionY: 15, width: 5, height: 5 },
|
||||
{
|
||||
type: FieldType.SIGNATURE,
|
||||
page: 1,
|
||||
positionX: 5,
|
||||
positionY: 20,
|
||||
width: 5,
|
||||
height: 5,
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
const { token } = distributeResult.recipients[0];
|
||||
|
||||
// Resolve the fields from the envelope for position calculations.
|
||||
const fields = envelope.fields;
|
||||
|
||||
await page.goto(`/sign/${token}`);
|
||||
|
||||
// wait for PDF to be visible
|
||||
await expect(page.locator(PDF_PAGE_SELECTOR).first()).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
// Wait for the Konva canvas to be ready.
|
||||
const canvas = page.locator('.konva-container canvas').first();
|
||||
await expect(canvas).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
// DATE and EMAIL fields are auto-filled, so only NAME and SIGNATURE remain.
|
||||
await expect(page.getByText('2 Fields Remaining').first()).toBeVisible();
|
||||
|
||||
// Set up a signature via the sidebar form.
|
||||
await page.getByTestId('signature-pad-dialog-button').click();
|
||||
await page.getByRole('tab', { name: 'Type' }).click();
|
||||
await page.getByTestId('signature-pad-type-input').fill('Signature');
|
||||
await page.getByRole('button', { name: 'Next' }).click();
|
||||
|
||||
// Click each non-date field on the Konva canvas to insert it.
|
||||
// Fields are seeded with positions as percentages of the page.
|
||||
// We need to convert these percentages to pixel positions on the canvas.
|
||||
const canvasBox = await canvas.boundingBox();
|
||||
|
||||
if (!canvasBox) {
|
||||
throw new Error('Canvas bounding box not found');
|
||||
}
|
||||
|
||||
// Only NAME and SIGNATURE fields need manual interaction (DATE and EMAIL are auto-filled).
|
||||
const manualFields = fields.filter(
|
||||
(f) => f.type !== FieldType.DATE && f.type !== FieldType.EMAIL,
|
||||
);
|
||||
|
||||
for (const field of manualFields) {
|
||||
const x =
|
||||
(Number(field.positionX) / 100) * canvasBox.width +
|
||||
((Number(field.width) / 100) * canvasBox.width) / 2;
|
||||
const y =
|
||||
(Number(field.positionY) / 100) * canvasBox.height +
|
||||
((Number(field.height) / 100) * canvasBox.height) / 2;
|
||||
|
||||
await canvas.click({ position: { x, y } });
|
||||
|
||||
if (field.type === FieldType.NAME) {
|
||||
const nameDialog = page.getByRole('dialog');
|
||||
const isDialogVisible = await nameDialog.isVisible().catch(() => false);
|
||||
|
||||
if (isDialogVisible) {
|
||||
const nameInput = nameDialog.locator('input[type="text"], input[name="name"]').first();
|
||||
const isInputVisible = await nameInput.isVisible().catch(() => false);
|
||||
|
||||
if (isInputVisible) {
|
||||
await nameInput.fill('Test Signer');
|
||||
}
|
||||
|
||||
const saveButton = nameDialog.getByRole('button', { name: 'Save' });
|
||||
const isButtonVisible = await saveButton.isVisible().catch(() => false);
|
||||
|
||||
if (isButtonVisible) {
|
||||
await saveButton.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Small delay to allow the field signing to complete.
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
// All fields should now be complete.
|
||||
await expect(page.getByText('0 Fields Remaining').first()).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
await page.getByRole('button', { name: 'Complete' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Are you sure?' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Sign' }).click();
|
||||
|
||||
await page.waitForURL(`/sign/${token}/complete`);
|
||||
await expect(page.getByText('Document Signed')).toBeVisible();
|
||||
|
||||
// Verify the date field was auto-inserted with the correct format.
|
||||
const dateField = await prisma.field.findFirstOrThrow({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
type: FieldType.DATE,
|
||||
},
|
||||
});
|
||||
|
||||
expect(dateField.inserted).toBe(true);
|
||||
expect(dateField.customText).toBeTruthy();
|
||||
|
||||
const insertedDate = DateTime.fromFormat(dateField.customText, DEFAULT_DOCUMENT_DATE_FORMAT, {
|
||||
zone: DEFAULT_DOCUMENT_TIME_ZONE,
|
||||
});
|
||||
|
||||
expect(insertedDate.isValid).toBe(true);
|
||||
expect(Math.abs(insertedDate.diff(now, 'minutes').minutes)).toBeLessThanOrEqual(2);
|
||||
|
||||
// Verify the email field was inserted with the recipient's email.
|
||||
const emailField = await prisma.field.findFirstOrThrow({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
type: FieldType.EMAIL,
|
||||
},
|
||||
});
|
||||
|
||||
expect(emailField.inserted).toBe(true);
|
||||
expect(emailField.customText).toBe(recipientEmail);
|
||||
|
||||
// Verify all fields are inserted.
|
||||
const allFields = await prisma.field.findMany({
|
||||
where: { envelopeId: envelope.id },
|
||||
});
|
||||
|
||||
for (const field of allFields) {
|
||||
expect(field.inserted).toBe(true);
|
||||
}
|
||||
|
||||
// Verify the document reached COMPLETED status.
|
||||
await expect(async () => {
|
||||
const dbEnvelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: envelope.id },
|
||||
});
|
||||
|
||||
expect(dbEnvelope.status).toBe(DocumentStatus.COMPLETED);
|
||||
}).toPass();
|
||||
});
|
||||
});
|
||||
901
packages/app-tests/e2e/fixtures/api-seeds.ts
Normal file
901
packages/app-tests/e2e/fixtures/api-seeds.ts
Normal file
|
|
@ -0,0 +1,901 @@
|
|||
/**
|
||||
* API V2-based seed fixtures for E2E tests.
|
||||
*
|
||||
* These fixtures create documents, templates, envelopes, recipients, fields,
|
||||
* and folders through the API V2 endpoints instead of direct Prisma calls.
|
||||
* This ensures all creation-time side effects (PDF normalization, field meta
|
||||
* defaults, etc.) are exercised the same way a real user would trigger them.
|
||||
*
|
||||
* Usage:
|
||||
* import { apiSeedDraftDocument, apiSeedPendingDocument, ... } from '../fixtures/api-seeds';
|
||||
*
|
||||
* test('my test', async ({ request }) => {
|
||||
* const { envelope, token, user, team } = await apiSeedDraftDocument(request, {
|
||||
* title: 'My Document',
|
||||
* recipients: [{ email: 'signer@example.com', name: 'Signer', role: 'SIGNER' }],
|
||||
* });
|
||||
* });
|
||||
*/
|
||||
import { type APIRequestContext, expect } from '@playwright/test';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
import type {
|
||||
TDistributeEnvelopeRequest,
|
||||
TDistributeEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/distribute-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsResponse } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Constants
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const API_BASE_URL = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
const examplePdfBuffer = fs.readFileSync(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type ApiRecipient = {
|
||||
email: string;
|
||||
name?: string;
|
||||
role?: 'SIGNER' | 'APPROVER' | 'VIEWER' | 'CC' | 'ASSISTANT';
|
||||
signingOrder?: number;
|
||||
accessAuth?: string[];
|
||||
actionAuth?: string[];
|
||||
};
|
||||
|
||||
export type ApiField = {
|
||||
recipientId: number;
|
||||
envelopeItemId?: string;
|
||||
type: string;
|
||||
page?: number;
|
||||
positionX?: number;
|
||||
positionY?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
fieldMeta?: Record<string, unknown>;
|
||||
placeholder?: string;
|
||||
matchAll?: boolean;
|
||||
};
|
||||
|
||||
export type ApiSeedContext = {
|
||||
user: Awaited<ReturnType<typeof seedUser>>['user'];
|
||||
team: Awaited<ReturnType<typeof seedUser>>['team'];
|
||||
token: string;
|
||||
};
|
||||
|
||||
export type ApiSeedEnvelopeOptions = {
|
||||
title?: string;
|
||||
type?: 'DOCUMENT' | 'TEMPLATE';
|
||||
externalId?: string;
|
||||
visibility?: string;
|
||||
globalAccessAuth?: string[];
|
||||
globalActionAuth?: string[];
|
||||
folderId?: string;
|
||||
pdfFile?: { name: string; data: Buffer };
|
||||
meta?: TCreateEnvelopePayload['meta'];
|
||||
recipients?: Array<
|
||||
ApiRecipient & {
|
||||
fields?: Array<{
|
||||
type: string;
|
||||
identifier?: string | number;
|
||||
page?: number;
|
||||
positionX?: number;
|
||||
positionY?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
fieldMeta?: Record<string, unknown>;
|
||||
}>;
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Core API helpers (low-level)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a fresh user + team + API token for test isolation.
|
||||
* Every high-level seed function calls this internally, but you can also
|
||||
* call it directly if you need the context for multiple operations.
|
||||
*/
|
||||
export const apiCreateTestContext = async (tokenName = 'e2e-seed'): Promise<ApiSeedContext> => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName,
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
return { user, team, token };
|
||||
};
|
||||
|
||||
const authHeader = (token: string) => ({
|
||||
Authorization: `Bearer ${token}`,
|
||||
});
|
||||
|
||||
/**
|
||||
* Create an envelope via API V2 with a PDF file attached.
|
||||
*
|
||||
* This is the lowest-level envelope creation function. It creates the
|
||||
* envelope with optional inline recipients and fields in a single call.
|
||||
*/
|
||||
export const apiCreateEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
options: ApiSeedEnvelopeOptions = {},
|
||||
): Promise<TCreateEnvelopeResponse> => {
|
||||
const {
|
||||
title = '[TEST] API Seeded Envelope',
|
||||
type = 'DOCUMENT',
|
||||
externalId,
|
||||
visibility,
|
||||
globalAccessAuth,
|
||||
globalActionAuth,
|
||||
folderId,
|
||||
pdfFile,
|
||||
meta,
|
||||
recipients,
|
||||
} = options;
|
||||
|
||||
// Build payload as a plain object. The API receives this as a JSON string
|
||||
// inside multipart form data, so strict TypeScript union narrowing is not
|
||||
// required - the server validates with Zod at runtime.
|
||||
const payload: Record<string, unknown> = {
|
||||
title,
|
||||
type,
|
||||
};
|
||||
|
||||
if (externalId !== undefined) {
|
||||
payload.externalId = externalId;
|
||||
}
|
||||
|
||||
if (visibility !== undefined) {
|
||||
payload.visibility = visibility;
|
||||
}
|
||||
|
||||
if (globalAccessAuth !== undefined) {
|
||||
payload.globalAccessAuth = globalAccessAuth;
|
||||
}
|
||||
|
||||
if (globalActionAuth !== undefined) {
|
||||
payload.globalActionAuth = globalActionAuth;
|
||||
}
|
||||
|
||||
if (folderId !== undefined) {
|
||||
payload.folderId = folderId;
|
||||
}
|
||||
|
||||
if (meta !== undefined) {
|
||||
payload.meta = meta;
|
||||
}
|
||||
|
||||
if (recipients !== undefined) {
|
||||
payload.recipients = recipients.map((r) => {
|
||||
const recipientPayload: Record<string, unknown> = {
|
||||
email: r.email,
|
||||
name: r.name ?? r.email,
|
||||
role: r.role ?? 'SIGNER',
|
||||
};
|
||||
|
||||
if (r.signingOrder !== undefined) {
|
||||
recipientPayload.signingOrder = r.signingOrder;
|
||||
}
|
||||
|
||||
if (r.accessAuth !== undefined) {
|
||||
recipientPayload.accessAuth = r.accessAuth;
|
||||
}
|
||||
|
||||
if (r.actionAuth !== undefined) {
|
||||
recipientPayload.actionAuth = r.actionAuth;
|
||||
}
|
||||
|
||||
if (r.fields !== undefined) {
|
||||
recipientPayload.fields = r.fields.map((f) => {
|
||||
const fieldPayload: Record<string, unknown> = {
|
||||
type: f.type,
|
||||
page: f.page ?? 1,
|
||||
positionX: f.positionX ?? 10,
|
||||
positionY: f.positionY ?? 10,
|
||||
width: f.width ?? 15,
|
||||
height: f.height ?? 5,
|
||||
};
|
||||
|
||||
if (f.identifier !== undefined) {
|
||||
fieldPayload.identifier = f.identifier;
|
||||
}
|
||||
|
||||
if (f.fieldMeta !== undefined) {
|
||||
fieldPayload.fieldMeta = f.fieldMeta;
|
||||
}
|
||||
|
||||
return fieldPayload;
|
||||
});
|
||||
}
|
||||
|
||||
return recipientPayload;
|
||||
});
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
|
||||
const pdf = pdfFile ?? { name: 'example.pdf', data: examplePdfBuffer };
|
||||
formData.append('files', new File([pdf.data], pdf.name, { type: 'application/pdf' }));
|
||||
|
||||
const res = await request.post(`${API_BASE_URL}/envelope/create`, {
|
||||
headers: authHeader(token),
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok(), `envelope/create failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return (await res.json()) as TCreateEnvelopeResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get full envelope data via API V2.
|
||||
*/
|
||||
export const apiGetEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
envelopeId: string,
|
||||
): Promise<TGetEnvelopeResponse> => {
|
||||
const res = await request.get(`${API_BASE_URL}/envelope/${envelopeId}`, {
|
||||
headers: authHeader(token),
|
||||
});
|
||||
|
||||
expect(res.ok(), `envelope/get failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return (await res.json()) as TGetEnvelopeResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add recipients to an existing envelope via API V2.
|
||||
*/
|
||||
export const apiCreateRecipients = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
envelopeId: string,
|
||||
recipients: ApiRecipient[],
|
||||
): Promise<TCreateEnvelopeRecipientsResponse> => {
|
||||
const data = {
|
||||
envelopeId,
|
||||
data: recipients.map((r) => {
|
||||
const recipientPayload: Record<string, unknown> = {
|
||||
email: r.email,
|
||||
name: r.name ?? r.email,
|
||||
role: r.role ?? 'SIGNER',
|
||||
};
|
||||
|
||||
if (r.signingOrder !== undefined) {
|
||||
recipientPayload.signingOrder = r.signingOrder;
|
||||
}
|
||||
|
||||
if (r.accessAuth !== undefined) {
|
||||
recipientPayload.accessAuth = r.accessAuth;
|
||||
}
|
||||
|
||||
if (r.actionAuth !== undefined) {
|
||||
recipientPayload.actionAuth = r.actionAuth;
|
||||
}
|
||||
|
||||
return recipientPayload;
|
||||
}),
|
||||
};
|
||||
|
||||
const res = await request.post(`${API_BASE_URL}/envelope/recipient/create-many`, {
|
||||
headers: { ...authHeader(token), 'Content-Type': 'application/json' },
|
||||
data,
|
||||
});
|
||||
|
||||
expect(res.ok(), `recipient/create-many failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return (await res.json()) as TCreateEnvelopeRecipientsResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add fields to an existing envelope via API V2.
|
||||
*
|
||||
* If `recipientId` is not set on fields, the first recipient is used.
|
||||
* If `envelopeItemId` is not set, the first envelope item is used.
|
||||
*/
|
||||
export const apiCreateFields = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
envelopeId: string,
|
||||
fields: ApiField[],
|
||||
): Promise<void> => {
|
||||
// Build as plain object - the deeply discriminated union types for fields
|
||||
// (type + fieldMeta combinations) are validated by Zod on the server.
|
||||
const data = {
|
||||
envelopeId,
|
||||
data: fields.map((f) => {
|
||||
const fieldPayload: Record<string, unknown> = {
|
||||
recipientId: f.recipientId,
|
||||
type: f.type,
|
||||
};
|
||||
|
||||
if (f.envelopeItemId !== undefined) {
|
||||
fieldPayload.envelopeItemId = f.envelopeItemId;
|
||||
}
|
||||
|
||||
if (f.fieldMeta !== undefined) {
|
||||
fieldPayload.fieldMeta = f.fieldMeta;
|
||||
}
|
||||
|
||||
if (f.placeholder) {
|
||||
fieldPayload.placeholder = f.placeholder;
|
||||
|
||||
if (f.width !== undefined) {
|
||||
fieldPayload.width = f.width;
|
||||
}
|
||||
|
||||
if (f.height !== undefined) {
|
||||
fieldPayload.height = f.height;
|
||||
}
|
||||
|
||||
if (f.matchAll !== undefined) {
|
||||
fieldPayload.matchAll = f.matchAll;
|
||||
}
|
||||
} else {
|
||||
fieldPayload.page = f.page ?? 1;
|
||||
fieldPayload.positionX = f.positionX ?? 10;
|
||||
fieldPayload.positionY = f.positionY ?? 10;
|
||||
fieldPayload.width = f.width ?? 15;
|
||||
fieldPayload.height = f.height ?? 5;
|
||||
}
|
||||
|
||||
return fieldPayload;
|
||||
}),
|
||||
};
|
||||
|
||||
const res = await request.post(`${API_BASE_URL}/envelope/field/create-many`, {
|
||||
headers: { ...authHeader(token), 'Content-Type': 'application/json' },
|
||||
data,
|
||||
});
|
||||
|
||||
expect(res.ok(), `field/create-many failed: ${await res.text()}`).toBeTruthy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Distribute (send) an envelope via API V2.
|
||||
* Returns the distribute response which includes signing URLs for recipients.
|
||||
*/
|
||||
export const apiDistributeEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
envelopeId: string,
|
||||
meta?: TDistributeEnvelopeRequest['meta'],
|
||||
): Promise<TDistributeEnvelopeResponse> => {
|
||||
const data: TDistributeEnvelopeRequest = {
|
||||
envelopeId,
|
||||
...(meta !== undefined && { meta }),
|
||||
};
|
||||
|
||||
const res = await request.post(`${API_BASE_URL}/envelope/distribute`, {
|
||||
headers: { ...authHeader(token), 'Content-Type': 'application/json' },
|
||||
data,
|
||||
});
|
||||
|
||||
expect(res.ok(), `envelope/distribute failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return (await res.json()) as TDistributeEnvelopeResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a folder via API V2.
|
||||
*/
|
||||
export const apiCreateFolder = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
options: {
|
||||
name?: string;
|
||||
parentId?: string;
|
||||
type?: 'DOCUMENT' | 'TEMPLATE';
|
||||
} = {},
|
||||
): Promise<{ id: string; name: string }> => {
|
||||
const { name = 'Test Folder', parentId, type } = options;
|
||||
|
||||
const res = await request.post(`${API_BASE_URL}/folder/create`, {
|
||||
headers: { ...authHeader(token), 'Content-Type': 'application/json' },
|
||||
data: {
|
||||
name,
|
||||
...(parentId !== undefined && { parentId }),
|
||||
...(type !== undefined && { type }),
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok(), `folder/create failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return (await res.json()) as { id: string; name: string };
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a direct template link via API V2.
|
||||
*/
|
||||
export const apiCreateDirectTemplateLink = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
templateId: number,
|
||||
directRecipientId?: number,
|
||||
): Promise<{ id: number; token: string; enabled: boolean; directTemplateRecipientId: number }> => {
|
||||
const res = await request.post(`${API_BASE_URL}/template/direct/create`, {
|
||||
headers: { ...authHeader(token), 'Content-Type': 'application/json' },
|
||||
data: {
|
||||
templateId,
|
||||
...(directRecipientId !== undefined && { directRecipientId }),
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok(), `template/direct/create failed: ${await res.text()}`).toBeTruthy();
|
||||
|
||||
return await res.json();
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// High-level seed functions (composites)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type ApiSeedResult = {
|
||||
/** The created envelope/document/template. */
|
||||
envelope: TGetEnvelopeResponse;
|
||||
/** API token for further API calls. */
|
||||
token: string;
|
||||
/** The seeded user. */
|
||||
user: ApiSeedContext['user'];
|
||||
/** The seeded team. */
|
||||
team: ApiSeedContext['team'];
|
||||
};
|
||||
|
||||
export type ApiSeedDocumentOptions = {
|
||||
/** Document title. Default: '[TEST] API Document - Draft' */
|
||||
title?: string;
|
||||
/** Recipients to add to the document. */
|
||||
recipients?: ApiRecipient[];
|
||||
/** Fields to add per recipient. If provided, must match recipients order. */
|
||||
fieldsPerRecipient?: Array<
|
||||
Array<{
|
||||
type: string;
|
||||
page?: number;
|
||||
positionX?: number;
|
||||
positionY?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
fieldMeta?: Record<string, unknown>;
|
||||
}>
|
||||
>;
|
||||
/** External ID for the envelope. */
|
||||
externalId?: string;
|
||||
/** Document visibility setting. */
|
||||
visibility?: string;
|
||||
/** Global access auth requirements. */
|
||||
globalAccessAuth?: string[];
|
||||
/** Global action auth requirements. */
|
||||
globalActionAuth?: string[];
|
||||
/** Folder ID to place the document in. */
|
||||
folderId?: string;
|
||||
/** Document meta settings. */
|
||||
meta?: TCreateEnvelopePayload['meta'];
|
||||
/** Custom PDF file. Default: example.pdf */
|
||||
pdfFile?: { name: string; data: Buffer };
|
||||
/** Reuse an existing test context instead of creating a new one. */
|
||||
context?: ApiSeedContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a draft document via API V2.
|
||||
*
|
||||
* Creates a user, team, API token, and a DRAFT document. Optionally adds
|
||||
* recipients and fields.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const { envelope, token, user, team } = await apiSeedDraftDocument(request, {
|
||||
* title: 'My Document',
|
||||
* recipients: [{ email: 'signer@test.com', name: 'Test Signer' }],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export const apiSeedDraftDocument = async (
|
||||
request: APIRequestContext,
|
||||
options: ApiSeedDocumentOptions = {},
|
||||
): Promise<ApiSeedResult> => {
|
||||
const ctx = options.context ?? (await apiCreateTestContext('e2e-draft-doc'));
|
||||
|
||||
// Create the envelope with inline recipients if provided
|
||||
const createOptions: ApiSeedEnvelopeOptions = {
|
||||
title: options.title ?? '[TEST] API Document - Draft',
|
||||
type: 'DOCUMENT',
|
||||
externalId: options.externalId,
|
||||
visibility: options.visibility,
|
||||
globalAccessAuth: options.globalAccessAuth,
|
||||
globalActionAuth: options.globalActionAuth,
|
||||
folderId: options.folderId,
|
||||
meta: options.meta,
|
||||
pdfFile: options.pdfFile,
|
||||
};
|
||||
|
||||
// If we have recipients but no per-recipient fields, use inline creation
|
||||
if (options.recipients && !options.fieldsPerRecipient) {
|
||||
createOptions.recipients = options.recipients.map((r) => ({
|
||||
...r,
|
||||
role: r.role ?? 'SIGNER',
|
||||
}));
|
||||
}
|
||||
|
||||
const { id: envelopeId } = await apiCreateEnvelope(request, ctx.token, createOptions);
|
||||
|
||||
// If we need per-recipient fields, add recipients and fields separately
|
||||
if (options.recipients && options.fieldsPerRecipient) {
|
||||
const recipientsRes = await apiCreateRecipients(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
options.recipients,
|
||||
);
|
||||
|
||||
// Get envelope to resolve envelope item IDs
|
||||
const envelopeData = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
const firstItemId = envelopeData.envelopeItems[0]?.id;
|
||||
|
||||
// Create fields for each recipient
|
||||
for (const [index, recipientFields] of options.fieldsPerRecipient.entries()) {
|
||||
if (recipientFields.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const recipientId = recipientsRes.data[index].id;
|
||||
|
||||
await apiCreateFields(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
recipientFields.map((f) => ({
|
||||
...f,
|
||||
recipientId,
|
||||
envelopeItemId: firstItemId,
|
||||
type: f.type,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const envelope = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
|
||||
return { envelope, token: ctx.token, user: ctx.user, team: ctx.team };
|
||||
};
|
||||
|
||||
export type ApiSeedPendingDocumentOptions = ApiSeedDocumentOptions & {
|
||||
/** Distribution meta (subject, message, etc.). */
|
||||
distributeMeta?: TDistributeEnvelopeRequest['meta'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Seed a pending (distributed) document via API V2.
|
||||
*
|
||||
* Creates the document, adds recipients with SIGNATURE fields, then
|
||||
* distributes (sends) it. The response includes signing URLs for each
|
||||
* recipient.
|
||||
*
|
||||
* Every SIGNER recipient must have at least one SIGNATURE field for
|
||||
* distribution to succeed. If you don't provide `fieldsPerRecipient`,
|
||||
* a default SIGNATURE field is added for each SIGNER/APPROVER recipient.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const { envelope, distributeResult, token } = await apiSeedPendingDocument(request, {
|
||||
* recipients: [
|
||||
* { email: 'signer@test.com', name: 'Signer' },
|
||||
* { email: 'viewer@test.com', name: 'Viewer', role: 'VIEWER' },
|
||||
* ],
|
||||
* });
|
||||
*
|
||||
* // Access signing URL:
|
||||
* const signingUrl = distributeResult.recipients[0].signingUrl;
|
||||
* ```
|
||||
*/
|
||||
export const apiSeedPendingDocument = async (
|
||||
request: APIRequestContext,
|
||||
options: ApiSeedPendingDocumentOptions = {},
|
||||
): Promise<
|
||||
ApiSeedResult & {
|
||||
distributeResult: TDistributeEnvelopeResponse;
|
||||
}
|
||||
> => {
|
||||
const ctx = options.context ?? (await apiCreateTestContext('e2e-pending-doc'));
|
||||
|
||||
const recipients = options.recipients ?? [
|
||||
{
|
||||
email: `signer-${Date.now()}@test.documenso.com`,
|
||||
name: 'Test Signer',
|
||||
role: 'SIGNER' as const,
|
||||
},
|
||||
];
|
||||
|
||||
// Create the base envelope
|
||||
const { id: envelopeId } = await apiCreateEnvelope(request, ctx.token, {
|
||||
title: options.title ?? '[TEST] API Document - Pending',
|
||||
type: 'DOCUMENT',
|
||||
externalId: options.externalId,
|
||||
visibility: options.visibility,
|
||||
globalAccessAuth: options.globalAccessAuth,
|
||||
globalActionAuth: options.globalActionAuth,
|
||||
folderId: options.folderId,
|
||||
meta: options.meta,
|
||||
pdfFile: options.pdfFile,
|
||||
});
|
||||
|
||||
// Add recipients
|
||||
const recipientsRes = await apiCreateRecipients(request, ctx.token, envelopeId, recipients);
|
||||
|
||||
// Get envelope for item IDs
|
||||
const envelopeData = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
const firstItemId = envelopeData.envelopeItems[0]?.id;
|
||||
|
||||
// Add fields
|
||||
if (options.fieldsPerRecipient) {
|
||||
for (const [index, recipientFields] of options.fieldsPerRecipient.entries()) {
|
||||
if (recipientFields.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await apiCreateFields(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
recipientFields.map((f) => ({
|
||||
...f,
|
||||
recipientId: recipientsRes.data[index].id,
|
||||
envelopeItemId: firstItemId,
|
||||
type: f.type,
|
||||
})),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Auto-add a SIGNATURE field for each SIGNER/APPROVER recipient
|
||||
const signerFields: ApiField[] = [];
|
||||
|
||||
for (const [index, r] of recipientsRes.data.entries()) {
|
||||
const role = recipients[index].role ?? 'SIGNER';
|
||||
|
||||
if (role === 'SIGNER' || role === 'APPROVER') {
|
||||
signerFields.push({
|
||||
recipientId: r.id,
|
||||
envelopeItemId: firstItemId,
|
||||
type: 'SIGNATURE',
|
||||
page: 1,
|
||||
positionX: 10,
|
||||
positionY: 10 + index * 10,
|
||||
width: 15,
|
||||
height: 5,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (signerFields.length > 0) {
|
||||
await apiCreateFields(request, ctx.token, envelopeId, signerFields);
|
||||
}
|
||||
}
|
||||
|
||||
// Distribute
|
||||
const distributeResult = await apiDistributeEnvelope(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
options.distributeMeta,
|
||||
);
|
||||
|
||||
const envelope = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
|
||||
return {
|
||||
envelope,
|
||||
distributeResult,
|
||||
token: ctx.token,
|
||||
user: ctx.user,
|
||||
team: ctx.team,
|
||||
};
|
||||
};
|
||||
|
||||
export type ApiSeedTemplateOptions = Omit<ApiSeedDocumentOptions, 'folderId'> & {
|
||||
/** Folder ID to place the template in. */
|
||||
folderId?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Seed a template via API V2.
|
||||
*
|
||||
* Creates a TEMPLATE envelope with optional recipients and fields.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const { envelope, token } = await apiSeedTemplate(request, {
|
||||
* title: 'My Template',
|
||||
* recipients: [{ email: 'recipient@test.com', name: 'Signer', role: 'SIGNER' }],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export const apiSeedTemplate = async (
|
||||
request: APIRequestContext,
|
||||
options: ApiSeedTemplateOptions = {},
|
||||
): Promise<ApiSeedResult> => {
|
||||
const ctx = options.context ?? (await apiCreateTestContext('e2e-template'));
|
||||
|
||||
const createOptions: ApiSeedEnvelopeOptions = {
|
||||
title: options.title ?? '[TEST] API Template',
|
||||
type: 'TEMPLATE',
|
||||
externalId: options.externalId,
|
||||
visibility: options.visibility,
|
||||
globalAccessAuth: options.globalAccessAuth,
|
||||
globalActionAuth: options.globalActionAuth,
|
||||
folderId: options.folderId,
|
||||
meta: options.meta,
|
||||
pdfFile: options.pdfFile,
|
||||
};
|
||||
|
||||
if (options.recipients && !options.fieldsPerRecipient) {
|
||||
createOptions.recipients = options.recipients.map((r) => ({
|
||||
...r,
|
||||
role: r.role ?? 'SIGNER',
|
||||
}));
|
||||
}
|
||||
|
||||
const { id: envelopeId } = await apiCreateEnvelope(request, ctx.token, createOptions);
|
||||
|
||||
if (options.recipients && options.fieldsPerRecipient) {
|
||||
const recipientsRes = await apiCreateRecipients(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
options.recipients,
|
||||
);
|
||||
|
||||
const envelopeData = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
const firstItemId = envelopeData.envelopeItems[0]?.id;
|
||||
|
||||
for (const [index, recipientFields] of options.fieldsPerRecipient.entries()) {
|
||||
if (recipientFields.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await apiCreateFields(
|
||||
request,
|
||||
ctx.token,
|
||||
envelopeId,
|
||||
recipientFields.map((f) => ({
|
||||
...f,
|
||||
recipientId: recipientsRes.data[index].id,
|
||||
envelopeItemId: firstItemId,
|
||||
type: f.type,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const envelope = await apiGetEnvelope(request, ctx.token, envelopeId);
|
||||
|
||||
return { envelope, token: ctx.token, user: ctx.user, team: ctx.team };
|
||||
};
|
||||
|
||||
/**
|
||||
* Seed a template with a direct link via API V2.
|
||||
*
|
||||
* Creates a template with a recipient, then creates a direct link for it.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const { envelope, directLink, token } = await apiSeedDirectTemplate(request, {
|
||||
* title: 'Direct Template',
|
||||
* });
|
||||
*
|
||||
* // Use directLink.token for the signing URL
|
||||
* ```
|
||||
*/
|
||||
export const apiSeedDirectTemplate = async (
|
||||
request: APIRequestContext,
|
||||
options: ApiSeedTemplateOptions & {
|
||||
/** Custom recipient for the direct link. Default: a SIGNER placeholder. */
|
||||
directRecipient?: ApiRecipient;
|
||||
} = {},
|
||||
): Promise<
|
||||
ApiSeedResult & {
|
||||
directLink: { id: number; token: string; enabled: boolean; directTemplateRecipientId: number };
|
||||
}
|
||||
> => {
|
||||
const recipients = options.recipients ?? [
|
||||
options.directRecipient ?? {
|
||||
email: 'direct-template-recipient@documenso.com',
|
||||
name: 'Direct Template Recipient',
|
||||
role: 'SIGNER' as const,
|
||||
},
|
||||
];
|
||||
|
||||
const templateResult = await apiSeedTemplate(request, {
|
||||
...options,
|
||||
recipients,
|
||||
});
|
||||
|
||||
// Find the recipient ID for the direct link
|
||||
const directRecipientEmail = options.directRecipient?.email ?? recipients[0].email;
|
||||
|
||||
const directRecipient = templateResult.envelope.recipients.find(
|
||||
(r) => r.email === directRecipientEmail,
|
||||
);
|
||||
|
||||
if (!directRecipient) {
|
||||
throw new Error(`Direct template recipient not found: ${directRecipientEmail}`);
|
||||
}
|
||||
|
||||
const numericTemplateId = mapSecondaryIdToTemplateId(templateResult.envelope.secondaryId);
|
||||
|
||||
const directLink = await apiCreateDirectTemplateLink(
|
||||
request,
|
||||
templateResult.token,
|
||||
numericTemplateId,
|
||||
directRecipient.id,
|
||||
);
|
||||
|
||||
// Re-fetch envelope to include directLink data
|
||||
const envelope = await apiGetEnvelope(request, templateResult.token, templateResult.envelope.id);
|
||||
|
||||
return {
|
||||
...templateResult,
|
||||
envelope,
|
||||
directLink,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Seed multiple draft documents in parallel for a single user context.
|
||||
*
|
||||
* Useful for tests that need multiple documents (e.g., bulk actions, find/filter tests).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const { documents, token, user, team } = await apiSeedMultipleDraftDocuments(request, [
|
||||
* { title: 'Doc A' },
|
||||
* { title: 'Doc B' },
|
||||
* { title: 'Doc C' },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
export const apiSeedMultipleDraftDocuments = async (
|
||||
request: APIRequestContext,
|
||||
documents: ApiSeedDocumentOptions[],
|
||||
context?: ApiSeedContext,
|
||||
): Promise<{
|
||||
documents: TGetEnvelopeResponse[];
|
||||
token: string;
|
||||
user: ApiSeedContext['user'];
|
||||
team: ApiSeedContext['team'];
|
||||
}> => {
|
||||
const ctx = context ?? (await apiCreateTestContext('e2e-multi-doc'));
|
||||
|
||||
const results = await Promise.all(
|
||||
documents.map(async (docOptions) =>
|
||||
apiSeedDraftDocument(request, { ...docOptions, context: ctx }),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
documents: results.map((r) => r.envelope),
|
||||
token: ctx.token,
|
||||
user: ctx.user,
|
||||
team: ctx.team,
|
||||
};
|
||||
};
|
||||
|
|
@ -22,7 +22,7 @@ import { seedUser } from '@documenso/prisma/seed/users';
|
|||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
|
||||
const PDF_PAGE_SELECTOR = 'img[data-page-number]';
|
||||
export const PDF_PAGE_SELECTOR = 'img[data-page-number]';
|
||||
|
||||
async function addSecondEnvelopeItem(envelopeId: string) {
|
||||
const firstItem = await prisma.envelopeItem.findFirstOrThrow({
|
||||
|
|
|
|||
|
|
@ -117,7 +117,13 @@ test('[TEMPLATES]: duplicate template', async ({ page }) => {
|
|||
await expect(page.getByRole('menuitem', { name: 'Duplicate' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
|
||||
await page.getByRole('button', { name: 'Duplicate' }).click();
|
||||
await expect(page.getByText('Template duplicated').first()).toBeVisible();
|
||||
await expect(page.getByText('Template Duplicated').first()).toBeVisible();
|
||||
|
||||
// The dialog should navigate to the new template's edit page.
|
||||
await page.waitForURL(/\/templates\/.*\/edit/);
|
||||
|
||||
// Navigate back to the templates list and verify the count is now 2.
|
||||
await page.goto(`/t/${team.url}/templates`);
|
||||
await expect(page.getByTestId('data-table-count')).toContainText('Showing 2 results');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test:dev": "NODE_OPTIONS=--experimental-require-module playwright test",
|
||||
"test-ui:dev": "NODE_OPTIONS=--experimental-require-module playwright test --ui",
|
||||
"test:e2e": "NODE_OPTIONS=--experimental-require-module NODE_ENV=test NEXT_PRIVATE_LOGGER_FILE_PATH=./logs.json start-server-and-test \"npm run start -w @documenso/remix\" http://localhost:3000 \"playwright test $E2E_TEST_PATH\""
|
||||
"test:dev": "NODE_OPTIONS='--import tsx' playwright test",
|
||||
"test-ui:dev": "NODE_OPTIONS='--import tsx' playwright test --ui",
|
||||
"test:e2e": "NODE_OPTIONS='--import tsx' NODE_ENV=test NEXT_PRIVATE_LOGGER_FILE_PATH=./logs.json start-server-and-test \"npm run start -w @documenso/remix\" http://localhost:3000 \"playwright test $E2E_TEST_PATH\""
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
|
@ -18,10 +18,11 @@
|
|||
"@playwright/test": "1.56.1",
|
||||
"@types/node": "^20",
|
||||
"@types/pngjs": "^6.0.5",
|
||||
"tsx": "^4.20.6",
|
||||
"pixelmatch": "^7.1.0",
|
||||
"pngjs": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"start-server-and-test": "^2.1.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
|
||||
export const ZCurrentPasswordSchema = z
|
||||
.string()
|
||||
.min(6, { message: 'Must be at least 6 characters in length' })
|
||||
.max(72);
|
||||
|
||||
export const ZSignInSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
password: ZCurrentPasswordSchema,
|
||||
totpCode: z.string().trim().optional(),
|
||||
backupCode: z.string().trim().optional(),
|
||||
|
|
@ -34,7 +36,7 @@ export const ZPasswordSchema = z
|
|||
|
||||
export const ZSignUpSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email(),
|
||||
email: zEmail(),
|
||||
password: ZPasswordSchema,
|
||||
signature: z.string().nullish(),
|
||||
});
|
||||
|
|
@ -42,7 +44,7 @@ export const ZSignUpSchema = z.object({
|
|||
export type TSignUpSchema = z.infer<typeof ZSignUpSchema>;
|
||||
|
||||
export const ZForgotPasswordSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
});
|
||||
|
||||
export type TForgotPasswordSchema = z.infer<typeof ZForgotPasswordSchema>;
|
||||
|
|
@ -61,7 +63,7 @@ export const ZVerifyEmailSchema = z.object({
|
|||
export type TVerifyEmailSchema = z.infer<typeof ZVerifyEmailSchema>;
|
||||
|
||||
export const ZResendVerifyEmailSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
email: zEmail().min(1),
|
||||
});
|
||||
|
||||
export type TResendVerifyEmailSchema = z.infer<typeof ZResendVerifyEmailSchema>;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export const createCheckoutSession = async ({
|
|||
],
|
||||
success_url: `${returnUrl}?success=true`,
|
||||
cancel_url: `${returnUrl}?canceled=true`,
|
||||
billing_address_collection: 'required',
|
||||
subscription_data: {
|
||||
metadata: subscriptionMetadata,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -64,9 +64,13 @@ const getTransport = (): Transporter => {
|
|||
}
|
||||
|
||||
if (transport === 'resend') {
|
||||
if (!env('NEXT_PRIVATE_RESEND_API_KEY')) {
|
||||
throw new Error('Resend transport requires NEXT_PRIVATE_RESEND_API_KEY');
|
||||
}
|
||||
|
||||
return createTransport(
|
||||
ResendTransport.makeTransport({
|
||||
apiKey: env('NEXT_PRIVATE_RESEND_API_KEY') || '',
|
||||
apiKey: env('NEXT_PRIVATE_RESEND_API_KEY'),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ const mapLocalRecipientsToRecipients = ({
|
|||
}, -1);
|
||||
|
||||
return localRecipients.map((recipient) => {
|
||||
const foundRecipient = envelope.recipients.find((recipient) => recipient.id === recipient.id);
|
||||
const foundRecipient = envelope.recipients.find((r) => r.id === recipient.id);
|
||||
|
||||
let recipientId = recipient.id;
|
||||
|
||||
|
|
|
|||
387
packages/lib/jobs/client/bullmq.ts
Normal file
387
packages/lib/jobs/client/bullmq.ts
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
import { createBullBoard } from '@bull-board/api';
|
||||
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
|
||||
import { HonoAdapter } from '@bull-board/hono';
|
||||
import { serveStatic } from '@hono/node-server/serve-static';
|
||||
import { sha256 } from '@noble/hashes/sha2';
|
||||
import { BackgroundJobStatus, Prisma } from '@prisma/client';
|
||||
import { Queue, Worker } from 'bullmq';
|
||||
import type { Job } from 'bullmq';
|
||||
import { Hono } from 'hono';
|
||||
import type { Context as HonoContext } from 'hono';
|
||||
import IORedis from 'ioredis';
|
||||
import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { env } from '../../utils/env';
|
||||
import type { JobDefinition, JobRunIO, SimpleTriggerJobOptions } from './_internal/job';
|
||||
import type { Json } from './_internal/json';
|
||||
import { BaseJobProvider } from './base';
|
||||
|
||||
const QUEUE_NAME = 'documenso-jobs';
|
||||
|
||||
const DEFAULT_CONCURRENCY = 10;
|
||||
const DEFAULT_MAX_RETRIES = 3;
|
||||
const DEFAULT_BACKOFF_DELAY = 1000;
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __documenso_bullmq_provider__: BullMQJobProvider | undefined;
|
||||
}
|
||||
|
||||
export class BullMQJobProvider extends BaseJobProvider {
|
||||
private _queue: Queue;
|
||||
private _worker: Worker;
|
||||
private _connection: IORedis;
|
||||
private _jobDefinitions: Record<string, JobDefinition> = {};
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
|
||||
const redisUrl = env('NEXT_PRIVATE_REDIS_URL');
|
||||
|
||||
if (!redisUrl) {
|
||||
throw new Error(
|
||||
'[JOBS]: NEXT_PRIVATE_REDIS_URL is required when using the BullMQ jobs provider',
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = env('NEXT_PRIVATE_REDIS_PREFIX') || 'documenso';
|
||||
|
||||
this._connection = new IORedis(redisUrl, {
|
||||
maxRetriesPerRequest: null,
|
||||
});
|
||||
|
||||
this._queue = new Queue(QUEUE_NAME, {
|
||||
connection: this._connection,
|
||||
prefix,
|
||||
});
|
||||
|
||||
const concurrency = Number(env('NEXT_PRIVATE_BULLMQ_CONCURRENCY')) || DEFAULT_CONCURRENCY;
|
||||
|
||||
this._worker = new Worker(
|
||||
QUEUE_NAME,
|
||||
async (job: Job) => {
|
||||
await this.processJob(job);
|
||||
},
|
||||
{
|
||||
connection: this._connection,
|
||||
prefix,
|
||||
concurrency,
|
||||
},
|
||||
);
|
||||
|
||||
this._worker.on('failed', (job, error) => {
|
||||
console.error(`[JOBS]: Job ${job?.name ?? 'unknown'} failed`, error);
|
||||
});
|
||||
|
||||
this._worker.on('error', (error) => {
|
||||
console.error('[JOBS]: Worker error', error);
|
||||
});
|
||||
|
||||
console.log(`[JOBS]: BullMQ provider initialized (concurrency: ${concurrency})`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses globalThis to store the singleton instance so that it's shared across
|
||||
* different bundles (e.g. Hono and Vite/React Router) at runtime.
|
||||
*/
|
||||
static getInstance() {
|
||||
if (globalThis.__documenso_bullmq_provider__) {
|
||||
return globalThis.__documenso_bullmq_provider__;
|
||||
}
|
||||
|
||||
const instance = new BullMQJobProvider();
|
||||
|
||||
globalThis.__documenso_bullmq_provider__ = instance;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public defineJob<N extends string, T>(definition: JobDefinition<N, T>) {
|
||||
this._jobDefinitions[definition.id] = {
|
||||
...definition,
|
||||
enabled: definition.enabled ?? true,
|
||||
};
|
||||
|
||||
if (definition.trigger.cron && definition.enabled !== false) {
|
||||
void this._queue
|
||||
.upsertJobScheduler(
|
||||
definition.id,
|
||||
{ pattern: definition.trigger.cron },
|
||||
{
|
||||
name: definition.id,
|
||||
data: {
|
||||
name: definition.trigger.name,
|
||||
payload: {},
|
||||
},
|
||||
opts: {
|
||||
attempts: DEFAULT_MAX_RETRIES,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: DEFAULT_BACKOFF_DELAY,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
.then(() => {
|
||||
console.log(`[JOBS]: Registered cron job ${definition.id} (${definition.trigger.cron})`);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`[JOBS]: Failed to register cron job ${definition.id}`, error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async triggerJob(options: SimpleTriggerJobOptions) {
|
||||
const eligibleJobs = Object.values(this._jobDefinitions).filter(
|
||||
(job) => job.trigger.name === options.name,
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
eligibleJobs.map(async (job) => {
|
||||
const backgroundJob = await prisma.backgroundJob.create({
|
||||
data: {
|
||||
jobId: job.id,
|
||||
name: job.name,
|
||||
version: job.version,
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
payload: options.payload as Prisma.InputJsonValue,
|
||||
},
|
||||
});
|
||||
|
||||
await this._queue.add(
|
||||
job.id,
|
||||
{
|
||||
name: options.name,
|
||||
payload: options.payload,
|
||||
backgroundJobId: backgroundJob.id,
|
||||
},
|
||||
{
|
||||
jobId: options.id,
|
||||
attempts: DEFAULT_MAX_RETRIES,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: DEFAULT_BACKOFF_DELAY,
|
||||
},
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public override getApiHandler(): (c: HonoContext) => Promise<Response | void> {
|
||||
const boardApp = this.createBoardApp();
|
||||
|
||||
return async (c: HonoContext) => {
|
||||
const reqPath = new URL(c.req.url).pathname;
|
||||
|
||||
if (!reqPath.startsWith('/api/jobs/board')) {
|
||||
return c.text('OK', 200);
|
||||
}
|
||||
|
||||
// Auth check — open in dev, admin-only in production.
|
||||
if (env('NODE_ENV') !== 'development') {
|
||||
const { getOptionalSession } = await import('@documenso/auth/server/lib/utils/get-session');
|
||||
const { isAdmin } = await import('../../utils/is-admin');
|
||||
|
||||
const { user } = await getOptionalSession(c);
|
||||
|
||||
if (!user || !isAdmin(user)) {
|
||||
return c.text('Unauthorized', 401);
|
||||
}
|
||||
}
|
||||
|
||||
return boardApp.fetch(c.req.raw);
|
||||
};
|
||||
}
|
||||
|
||||
private createBoardApp(): Hono {
|
||||
const _require = createRequire(import.meta.url);
|
||||
const uiPackagePath = path.dirname(_require.resolve('@bull-board/ui/package.json'));
|
||||
|
||||
const serverAdapter = new HonoAdapter(serveStatic);
|
||||
|
||||
createBullBoard({
|
||||
queues: [new BullMQAdapter(this._queue)],
|
||||
serverAdapter,
|
||||
options: { uiBasePath: uiPackagePath },
|
||||
});
|
||||
|
||||
serverAdapter.setBasePath('/api/jobs/board');
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
app.route('/api/jobs/board', serverAdapter.registerPlugin());
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private async processJob(job: Job) {
|
||||
const definitionId = job.name;
|
||||
const definition = this._jobDefinitions[definitionId];
|
||||
|
||||
if (!definition) {
|
||||
console.error(`[JOBS]: No definition found for job ${definitionId}`);
|
||||
throw new Error(`No definition found for job ${definitionId}`);
|
||||
}
|
||||
|
||||
if (!definition.enabled) {
|
||||
console.log(`[JOBS]: Skipping disabled job ${definitionId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const jobData = job.data as {
|
||||
name: string;
|
||||
payload: unknown;
|
||||
backgroundJobId?: string;
|
||||
};
|
||||
|
||||
if (definition.trigger.schema) {
|
||||
const result = definition.trigger.schema.safeParse(jobData.payload);
|
||||
|
||||
if (!result.success) {
|
||||
console.error(`[JOBS]: Payload validation failed for ${definitionId}`, result.error);
|
||||
throw new Error(`Payload validation failed for ${definitionId}`);
|
||||
}
|
||||
}
|
||||
|
||||
const backgroundJobId = jobData.backgroundJobId;
|
||||
|
||||
if (backgroundJobId) {
|
||||
await prisma.backgroundJob
|
||||
.update({
|
||||
where: {
|
||||
id: backgroundJobId,
|
||||
status: BackgroundJobStatus.PENDING,
|
||||
},
|
||||
data: {
|
||||
status: BackgroundJobStatus.PROCESSING,
|
||||
retried: job.attemptsMade > 0 ? job.attemptsMade : 0,
|
||||
lastRetriedAt: job.attemptsMade > 0 ? new Date() : undefined,
|
||||
},
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
console.log(`[JOBS]: Processing job ${definitionId} with payload`, jobData.payload);
|
||||
|
||||
try {
|
||||
await definition.handler({
|
||||
payload: jobData.payload,
|
||||
io: this.createJobRunIO(backgroundJobId ?? job.id ?? definitionId),
|
||||
});
|
||||
|
||||
if (backgroundJobId) {
|
||||
await prisma.backgroundJob
|
||||
.update({
|
||||
where: { id: backgroundJobId },
|
||||
data: {
|
||||
status: BackgroundJobStatus.COMPLETED,
|
||||
completedAt: new Date(),
|
||||
},
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
} catch (error) {
|
||||
if (backgroundJobId) {
|
||||
const isFinalAttempt = job.attemptsMade >= (job.opts.attempts ?? DEFAULT_MAX_RETRIES) - 1;
|
||||
|
||||
await prisma.backgroundJob
|
||||
.update({
|
||||
where: { id: backgroundJobId },
|
||||
data: {
|
||||
status: isFinalAttempt ? BackgroundJobStatus.FAILED : BackgroundJobStatus.PENDING,
|
||||
completedAt: isFinalAttempt ? new Date() : undefined,
|
||||
},
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private createJobRunIO(jobId: string): JobRunIO {
|
||||
return {
|
||||
runTask: async <T extends void | Json>(cacheKey: string, callback: () => Promise<T>) => {
|
||||
const hashedKey = Buffer.from(sha256(cacheKey)).toString('hex');
|
||||
|
||||
let task = await prisma.backgroundJobTask.findFirst({
|
||||
where: {
|
||||
id: `task-${hashedKey}--${jobId}`,
|
||||
jobId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!task) {
|
||||
task = await prisma.backgroundJobTask.create({
|
||||
data: {
|
||||
id: `task-${hashedKey}--${jobId}`,
|
||||
name: cacheKey,
|
||||
jobId,
|
||||
status: BackgroundJobStatus.PENDING,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (task.status === BackgroundJobStatus.COMPLETED) {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return task.result as T;
|
||||
}
|
||||
|
||||
if (task.retried >= DEFAULT_MAX_RETRIES) {
|
||||
throw new Error('Task exceeded retries');
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await callback();
|
||||
|
||||
await prisma.backgroundJobTask.update({
|
||||
where: {
|
||||
id: task.id,
|
||||
jobId,
|
||||
},
|
||||
data: {
|
||||
status: BackgroundJobStatus.COMPLETED,
|
||||
result: result === null ? Prisma.JsonNull : result,
|
||||
completedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (err) {
|
||||
await prisma.backgroundJobTask.update({
|
||||
where: {
|
||||
id: task.id,
|
||||
jobId,
|
||||
},
|
||||
data: {
|
||||
status: BackgroundJobStatus.PENDING,
|
||||
retried: {
|
||||
increment: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`[JOBS:${task.id}] Task failed`, err);
|
||||
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
triggerJob: async (_cacheKey, payload) => await this.triggerJob(payload),
|
||||
logger: {
|
||||
debug: (...args) => console.debug(`[${jobId}]`, ...args),
|
||||
error: (...args) => console.error(`[${jobId}]`, ...args),
|
||||
info: (...args) => console.info(`[${jobId}]`, ...args),
|
||||
log: (...args) => console.log(`[${jobId}]`, ...args),
|
||||
warn: (...args) => console.warn(`[${jobId}]`, ...args),
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
wait: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import { match } from 'ts-pattern';
|
|||
import { env } from '../../utils/env';
|
||||
import type { JobDefinition, TriggerJobOptions } from './_internal/job';
|
||||
import type { BaseJobProvider as JobClientProvider } from './base';
|
||||
import { BullMQJobProvider } from './bullmq';
|
||||
import { InngestJobProvider } from './inngest';
|
||||
import { LocalJobProvider } from './local';
|
||||
|
||||
|
|
@ -12,6 +13,7 @@ export class JobClient<T extends ReadonlyArray<JobDefinition> = []> {
|
|||
public constructor(definitions: T) {
|
||||
this._provider = match(env('NEXT_PRIVATE_JOBS_PROVIDER'))
|
||||
.with('inngest', () => InngestJobProvider.getInstance())
|
||||
.with('bullmq', () => BullMQJobProvider.getInstance())
|
||||
.otherwise(() => LocalJobProvider.getInstance());
|
||||
|
||||
definitions.forEach((definition) => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
import { zEmail } from '../../../utils/zod';
|
||||
import type { JobDefinition } from '../../client/_internal/job';
|
||||
|
||||
const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID = 'send.signup.confirmation.email';
|
||||
|
||||
const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
|
||||
email: z.string().email(),
|
||||
email: zEmail(),
|
||||
force: z.boolean().optional(),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { BulkSendCompleteEmail } from '@documenso/email/templates/bulk-send-comp
|
|||
import { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
||||
import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
|
||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
||||
|
|
@ -22,7 +23,7 @@ import type { TBulkSendTemplateJobDefinition } from './bulk-send-template';
|
|||
const ZRecipientRowSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
email: z.union([
|
||||
z.string().email({ message: 'Value must be a valid email or empty string' }),
|
||||
zEmail('Value must be a valid email or empty string'),
|
||||
z.string().max(0, { message: 'Value must be a valid email or empty string' }),
|
||||
]),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
"@aws-sdk/cloudfront-signer": "^3.998.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.998.0",
|
||||
"@aws-sdk/signature-v4-crt": "^3.998.0",
|
||||
"@bull-board/api": "^6.20.6",
|
||||
"@bull-board/hono": "^6.20.6",
|
||||
"@bull-board/ui": "^6.20.6",
|
||||
"@documenso/assets": "*",
|
||||
"@documenso/email": "*",
|
||||
"@documenso/prisma": "*",
|
||||
|
|
@ -39,8 +42,10 @@
|
|||
"@team-plain/typescript-sdk": "^5.11.0",
|
||||
"@vvo/tzdb": "^6.196.0",
|
||||
"ai": "^5.0.104",
|
||||
"bullmq": "^5.71.1",
|
||||
"csv-parse": "^6.1.0",
|
||||
"inngest": "^3.45.1",
|
||||
"ioredis": "^5.10.1",
|
||||
"jose": "^6.1.2",
|
||||
"konva": "^10.0.9",
|
||||
"kysely": "0.28.8",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ import {
|
|||
SigningStatus,
|
||||
WebhookTriggerEvents,
|
||||
} from '@prisma/client';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
|
||||
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
|
||||
import {
|
||||
DOCUMENT_AUDIT_LOG_TYPE,
|
||||
RECIPIENT_DIFF_TYPE,
|
||||
|
|
@ -120,46 +123,6 @@ export const completeDocumentWithToken = async ({
|
|||
}
|
||||
}
|
||||
|
||||
const fields = await prisma.field.findMany({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
recipientId: recipient.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (fieldsContainUnsignedRequiredField(fields)) {
|
||||
throw new Error(`Recipient ${recipient.id} has unsigned fields`);
|
||||
}
|
||||
|
||||
let recipientName = recipient.name;
|
||||
let recipientEmail = recipient.email;
|
||||
|
||||
// Only trim the name if it's been derived.
|
||||
if (!recipientName) {
|
||||
recipientName = (
|
||||
recipientOverride?.name ||
|
||||
fields.find((field) => field.type === FieldType.NAME)?.customText ||
|
||||
''
|
||||
).trim();
|
||||
}
|
||||
|
||||
// Only trim the email if it's been derived.
|
||||
if (!recipient.email) {
|
||||
recipientEmail = (
|
||||
recipientOverride?.email ||
|
||||
fields.find((field) => field.type === FieldType.EMAIL)?.customText ||
|
||||
''
|
||||
)
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
if (!recipientEmail) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Recipient email is required',
|
||||
});
|
||||
}
|
||||
|
||||
// Check ACCESS AUTH 2FA validation during document completion
|
||||
const { derivedRecipientAccessAuth } = extractDocumentAuthMethods({
|
||||
documentAuth: envelope.authOptions,
|
||||
|
|
@ -218,6 +181,112 @@ export const completeDocumentWithToken = async ({
|
|||
});
|
||||
}
|
||||
|
||||
let fields = await prisma.field.findMany({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
recipientId: recipient.id,
|
||||
},
|
||||
});
|
||||
|
||||
// This should be scoped to the current recipient.
|
||||
const uninsertedDateFields = fields.filter(
|
||||
(field) => field.type === FieldType.DATE && !field.inserted,
|
||||
);
|
||||
|
||||
let recipientName = recipient.name;
|
||||
let recipientEmail = recipient.email;
|
||||
|
||||
// Only trim the name if it's been derived.
|
||||
if (!recipientName) {
|
||||
recipientName = (
|
||||
recipientOverride?.name ||
|
||||
fields.find((field) => field.type === FieldType.NAME)?.customText ||
|
||||
''
|
||||
).trim();
|
||||
}
|
||||
|
||||
// Only trim the email if it's been derived.
|
||||
if (!recipient.email) {
|
||||
recipientEmail = (
|
||||
recipientOverride?.email ||
|
||||
fields.find((field) => field.type === FieldType.EMAIL)?.customText ||
|
||||
''
|
||||
)
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
if (!recipientEmail) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Recipient email is required',
|
||||
});
|
||||
}
|
||||
|
||||
// Auto-insert all un-inserted date fields for V2 envelopes at completion time.
|
||||
if (envelope.internalVersion === 2 && uninsertedDateFields.length > 0) {
|
||||
const formattedDate = DateTime.now()
|
||||
.setZone(envelope.documentMeta?.timezone ?? DEFAULT_DOCUMENT_TIME_ZONE)
|
||||
.toFormat(envelope.documentMeta?.dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT);
|
||||
|
||||
const newDateFieldValues = {
|
||||
customText: formattedDate,
|
||||
inserted: true,
|
||||
};
|
||||
|
||||
await prisma.field.updateMany({
|
||||
where: {
|
||||
id: {
|
||||
in: uninsertedDateFields.map((field) => field.id),
|
||||
},
|
||||
},
|
||||
data: {
|
||||
...newDateFieldValues,
|
||||
},
|
||||
});
|
||||
|
||||
// Create audit log entries for each auto-inserted date field.
|
||||
await prisma.documentAuditLog.createMany({
|
||||
data: uninsertedDateFields.map((field) =>
|
||||
createDocumentAuditLogData({
|
||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED,
|
||||
envelopeId: envelope.id,
|
||||
user: {
|
||||
email: recipientEmail,
|
||||
name: recipientName,
|
||||
},
|
||||
requestMetadata,
|
||||
data: {
|
||||
recipientEmail: recipientEmail,
|
||||
recipientId: recipient.id,
|
||||
recipientName: recipientName,
|
||||
recipientRole: recipient.role,
|
||||
fieldId: field.secondaryId,
|
||||
field: {
|
||||
type: FieldType.DATE,
|
||||
data: formattedDate,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
// Update the local fields array so the subsequent validation check passes.
|
||||
fields = fields.map((field) => {
|
||||
if (field.type === FieldType.DATE && !field.inserted) {
|
||||
return {
|
||||
...field,
|
||||
...newDateFieldValues,
|
||||
};
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
}
|
||||
|
||||
if (fieldsContainUnsignedRequiredField(fields)) {
|
||||
throw new Error(`Recipient ${recipient.id} has unsigned fields`);
|
||||
}
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.recipient.update({
|
||||
where: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { DocumentData, Envelope, EnvelopeItem, Field } from '@prisma/client';
|
||||
import type { DocumentData, Envelope, EnvelopeItem, Field, Recipient } from '@prisma/client';
|
||||
import {
|
||||
DocumentSigningOrder,
|
||||
DocumentStatus,
|
||||
|
|
@ -18,6 +18,7 @@ import { prisma } from '@documenso/prisma';
|
|||
import { checkboxValidationSigns } from '@documenso/ui/primitives/document-flow/field-items-advanced-settings/constants';
|
||||
|
||||
import { validateCheckboxLength } from '../../advanced-fields-validation/validate-checkbox';
|
||||
import { DIRECT_TEMPLATE_RECIPIENT_EMAIL } from '../../constants/direct-templates';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { jobs } from '../../jobs/client';
|
||||
import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
|
||||
|
|
@ -207,7 +208,7 @@ export const sendDocument = async ({
|
|||
});
|
||||
}
|
||||
|
||||
const fieldToAutoInsert = extractFieldAutoInsertValues(unknownField);
|
||||
const fieldToAutoInsert = extractFieldAutoInsertValues(unknownField, recipient);
|
||||
|
||||
// Only auto-insert fields if the recipient has not been sent the document yet.
|
||||
if (fieldToAutoInsert && recipient.sendStatus !== SendStatus.SENT) {
|
||||
|
|
@ -374,6 +375,7 @@ const injectFormValuesIntoDocument = async (
|
|||
*/
|
||||
export const extractFieldAutoInsertValues = (
|
||||
unknownField: Field,
|
||||
recipient: Pick<Recipient, 'email'>,
|
||||
): { fieldId: number; customText: string } | null => {
|
||||
const parsedField = ZFieldAndMetaSchema.safeParse(unknownField);
|
||||
|
||||
|
|
@ -386,6 +388,18 @@ export const extractFieldAutoInsertValues = (
|
|||
const field = parsedField.data;
|
||||
const fieldId = unknownField.id;
|
||||
|
||||
// Auto insert email fields if the recipient has a valid email.
|
||||
if (
|
||||
field.type === FieldType.EMAIL &&
|
||||
isRecipientEmailValidForSending(recipient) &&
|
||||
recipient.email !== DIRECT_TEMPLATE_RECIPIENT_EMAIL
|
||||
) {
|
||||
return {
|
||||
fieldId,
|
||||
customText: recipient.email,
|
||||
};
|
||||
}
|
||||
|
||||
// Auto insert text fields with prefilled values.
|
||||
if (field.type === FieldType.TEXT) {
|
||||
const { text } = ZTextFieldMeta.parse(field.fieldMeta);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,25 @@ export interface DuplicateEnvelopeOptions {
|
|||
id: EnvelopeIdOptions;
|
||||
userId: number;
|
||||
teamId: number;
|
||||
overrides?: {
|
||||
duplicateAsTemplate?: boolean;
|
||||
includeRecipients?: boolean;
|
||||
includeFields?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelopeOptions) => {
|
||||
export const duplicateEnvelope = async ({
|
||||
id,
|
||||
userId,
|
||||
teamId,
|
||||
overrides,
|
||||
}: DuplicateEnvelopeOptions) => {
|
||||
const {
|
||||
duplicateAsTemplate = false,
|
||||
includeRecipients = true,
|
||||
includeFields = true,
|
||||
} = overrides ?? {};
|
||||
|
||||
const { envelopeWhereInput } = await getEnvelopeWhereInput({
|
||||
id,
|
||||
type: null,
|
||||
|
|
@ -72,8 +88,16 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
|||
});
|
||||
}
|
||||
|
||||
if (duplicateAsTemplate && envelope.type !== EnvelopeType.DOCUMENT) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, {
|
||||
message: 'Only documents can be saved as templates',
|
||||
});
|
||||
}
|
||||
|
||||
const targetType = duplicateAsTemplate ? EnvelopeType.TEMPLATE : envelope.type;
|
||||
|
||||
const [{ legacyNumberId, secondaryId }, createdDocumentMeta] = await Promise.all([
|
||||
envelope.type === EnvelopeType.DOCUMENT
|
||||
targetType === EnvelopeType.DOCUMENT
|
||||
? incrementDocumentId().then(({ documentId, formattedDocumentId }) => ({
|
||||
legacyNumberId: documentId,
|
||||
secondaryId: formattedDocumentId,
|
||||
|
|
@ -99,7 +123,7 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
|||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId,
|
||||
type: envelope.type,
|
||||
type: targetType,
|
||||
internalVersion: envelope.internalVersion,
|
||||
userId,
|
||||
teamId,
|
||||
|
|
@ -111,7 +135,7 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
|||
publicTitle: envelope.publicTitle ?? undefined,
|
||||
publicDescription: envelope.publicDescription ?? undefined,
|
||||
source:
|
||||
envelope.type === EnvelopeType.DOCUMENT ? DocumentSource.DOCUMENT : DocumentSource.TEMPLATE,
|
||||
targetType === EnvelopeType.DOCUMENT ? DocumentSource.DOCUMENT : DocumentSource.TEMPLATE,
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
|
|
@ -148,38 +172,42 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
|||
}),
|
||||
);
|
||||
|
||||
await pMap(
|
||||
envelope.recipients,
|
||||
async (recipient) =>
|
||||
prisma.recipient.create({
|
||||
data: {
|
||||
envelopeId: duplicatedEnvelope.id,
|
||||
email: recipient.email,
|
||||
name: recipient.name,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
fields: {
|
||||
createMany: {
|
||||
data: recipient.fields.map((field) => ({
|
||||
envelopeId: duplicatedEnvelope.id,
|
||||
envelopeItemId: oldEnvelopeItemToNewEnvelopeItemIdMap[field.envelopeItemId],
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
customText: '',
|
||||
inserted: false,
|
||||
fieldMeta: field.fieldMeta as PrismaJson.FieldMeta,
|
||||
})),
|
||||
},
|
||||
if (includeRecipients) {
|
||||
await pMap(
|
||||
envelope.recipients,
|
||||
async (recipient) =>
|
||||
prisma.recipient.create({
|
||||
data: {
|
||||
envelopeId: duplicatedEnvelope.id,
|
||||
email: recipient.email,
|
||||
name: recipient.name,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
fields: includeFields
|
||||
? {
|
||||
createMany: {
|
||||
data: recipient.fields.map((field) => ({
|
||||
envelopeId: duplicatedEnvelope.id,
|
||||
envelopeItemId: oldEnvelopeItemToNewEnvelopeItemIdMap[field.envelopeItemId],
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
customText: '',
|
||||
inserted: false,
|
||||
fieldMeta: field.fieldMeta as PrismaJson.FieldMeta,
|
||||
})),
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
},
|
||||
}),
|
||||
{ concurrency: 5 },
|
||||
);
|
||||
}),
|
||||
{ concurrency: 5 },
|
||||
);
|
||||
}
|
||||
|
||||
if (duplicatedEnvelope.type === EnvelopeType.DOCUMENT) {
|
||||
const refetchedEnvelope = await prisma.envelope.findFirstOrThrow({
|
||||
|
|
@ -204,7 +232,7 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
|||
id: duplicatedEnvelope.id,
|
||||
envelope: duplicatedEnvelope,
|
||||
legacyId: {
|
||||
type: envelope.type,
|
||||
type: duplicatedEnvelope.type,
|
||||
id: legacyNumberId,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ export const getEnvelopeForDirectTemplateSigning = async ({
|
|||
...recipient,
|
||||
directToken: envelope.directLink?.token || '',
|
||||
fields: recipient.fields.map((field) => {
|
||||
const autoInsertValue = extractFieldAutoInsertValues(field);
|
||||
const autoInsertValue = extractFieldAutoInsertValues(field, recipient);
|
||||
|
||||
if (!autoInsertValue) {
|
||||
return field;
|
||||
|
|
|
|||
|
|
@ -13,14 +13,31 @@ const MIN_CERT_PAGE_HEIGHT = 300;
|
|||
* Falls back to MediaBox when it's smaller than CropBox, following typical PDF reader behavior.
|
||||
*/
|
||||
export const getPageSize = (page: PDFPage) => {
|
||||
const cropBox = page.getCropBox();
|
||||
const mediaBox = page.getMediaBox();
|
||||
let mediaBox;
|
||||
let cropBox;
|
||||
|
||||
if (mediaBox.width < cropBox.width || mediaBox.height < cropBox.height) {
|
||||
return mediaBox;
|
||||
try {
|
||||
mediaBox = page.getMediaBox();
|
||||
} catch {
|
||||
// MediaBox lookup can fail for malformed PDFs where the entry is not a valid PDFArray.
|
||||
}
|
||||
|
||||
return cropBox;
|
||||
try {
|
||||
cropBox = page.getCropBox();
|
||||
} catch {
|
||||
// CropBox lookup can fail for malformed PDFs where the entry is not a valid PDFArray.
|
||||
}
|
||||
|
||||
if (mediaBox && cropBox) {
|
||||
if (mediaBox.width < cropBox.width || mediaBox.height < cropBox.height) {
|
||||
return mediaBox;
|
||||
}
|
||||
|
||||
return cropBox;
|
||||
}
|
||||
|
||||
// If either box is missing or invalid, fall back to MediaBox if available, otherwise CropBox, or default to A4 size.
|
||||
return mediaBox || cropBox || PDF_SIZE_A4_72PPI;
|
||||
};
|
||||
|
||||
export const getLastPageDimensions = (pdfDoc: PDF): { width: number; height: number } => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { withTimeout } from '../../utils/timeout';
|
|||
import { isPrivateUrl } from './is-private-url';
|
||||
|
||||
const ZIpSchema = z.string().ip();
|
||||
|
||||
const WEBHOOK_DNS_LOOKUP_TIMEOUT_MS = 250;
|
||||
|
||||
type TLookupAddress = {
|
||||
|
|
@ -26,9 +27,55 @@ const normalizeHostname = (hostname: string) => hostname.toLowerCase().replace(/
|
|||
const toAddressUrl = (address: string) =>
|
||||
address.includes(':') ? `http://[${address}]` : `http://${address}`;
|
||||
|
||||
/**
|
||||
* Parse the NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS environment variable into
|
||||
* a Set of lowercased hostnames/IPs that are allowed to resolve to private
|
||||
* addresses. The Set is built once at module load and never changes.
|
||||
*
|
||||
* Empty or unset = no bypasses (safe default).
|
||||
*/
|
||||
const webhookSSRFBypassHosts = (): Set<string> => {
|
||||
const raw = process.env['NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS'] ?? '';
|
||||
|
||||
const hosts = new Set<string>();
|
||||
|
||||
for (const entry of raw.split(',')) {
|
||||
const trimmed = entry.trim().toLowerCase();
|
||||
|
||||
if (trimmed.length > 0) {
|
||||
hosts.add(trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
return hosts;
|
||||
};
|
||||
|
||||
const WEBHOOK_SSRF_BYPASS_HOSTS = webhookSSRFBypassHosts();
|
||||
|
||||
/**
|
||||
* Check whether the hostname of the given URL is present in the SSRF bypass
|
||||
* list. Matches against URL.hostname which covers both DNS names and raw IP
|
||||
* addresses uniformly.
|
||||
*/
|
||||
const isBypassedHost = (url: string): boolean => {
|
||||
if (WEBHOOK_SSRF_BYPASS_HOSTS.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const hostname = normalizeHostname(new URL(url).hostname);
|
||||
|
||||
return WEBHOOK_SSRF_BYPASS_HOSTS.has(hostname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that a webhook URL does not resolve to a private or loopback
|
||||
* address. Throws an AppError with WEBHOOK_INVALID_REQUEST if it does.
|
||||
*
|
||||
* Hosts listed in NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS skip all checks.
|
||||
*/
|
||||
export const assertNotPrivateUrl = async (
|
||||
url: string,
|
||||
|
|
@ -36,6 +83,10 @@ export const assertNotPrivateUrl = async (
|
|||
lookup?: TLookupFn;
|
||||
},
|
||||
) => {
|
||||
if (isBypassedHost(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPrivateUrl(url)) {
|
||||
throw new AppError(AppErrorCode.WEBHOOK_INVALID_REQUEST, {
|
||||
message: 'Webhook URL resolves to a private or loopback address',
|
||||
|
|
@ -50,6 +101,7 @@ export const assertNotPrivateUrl = async (
|
|||
}
|
||||
|
||||
const resolveHostname = options?.lookup ?? lookup;
|
||||
|
||||
const lookupResult = await withTimeout(
|
||||
resolveHostname(hostname, {
|
||||
all: true,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Profil nicht gefunden"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Team nicht gefunden"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "Eine eindeutige URL zur Identifizierung Ihrer Organisation"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Eine eindeutige URL, um dein Team zu identifizieren"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "Eine gültige E-Mail-Adresse ist erforderlich"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Eine Bestätigungs-E-Mail wird an die angegebene E-Mail-Adresse gesendet."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "Zusätzliche Markeninformationen, die am Ende von E-Mails angezeigt werd
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "Nach der elektronischen Unterzeichnung eines Dokuments haben Sie die Mö
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Nach der Übermittlung wird ein Dokument automatisch generiert und zu Ihrer Dokumentenseite hinzugefügt. Sie erhalten außerdem eine Benachrichtigung per E-Mail."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "KI-Funktionen"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "KI‑Funktionen"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "Markendetails"
|
|||
msgid "Brand Website"
|
||||
msgstr "Marken-Website"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Marken"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Branding-Unternehmensdetails"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Branding-Logo"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Branding-Logo"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "Markenpräferenzen"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Markenpräferenzen aktualisiert"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "Branding-URL"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "Person nicht gefunden?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Steuert, wie lange Empfänger Zeit haben, die Signatur abzuschließen, bevor das Dokument abläuft. Nach dem Ablauf können Empfänger das Dokument nicht mehr unterschreiben."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Kontrolliert die Standard-E-Mail-Einstellungen, wenn neue Dokumente oder Vorlagen erstellt werden."
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Legt die standardmäßigen E-Mail-Einstellungen fest, wenn neue Dokumente oder Vorlagen erstellt werden. Das Aktualisieren dieser Einstellungen wirkt sich nicht auf bestehende Dokumente oder Vorlagen aus."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "Feld in die Zwischenablage kopiert"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "Kopieren"
|
|||
msgid "Copy Link"
|
||||
msgstr "Link kopieren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Organisations-ID kopieren"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Kopieren Sie den teilbaren Link"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "Kopiere den teilbaren Link"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Signierlinks kopieren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Team-ID kopieren"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Token kopieren"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "Erstellen Sie ein Support-Ticket"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Ein Team erstellen, um mit Ihren Teammitgliedern zusammenzuarbeiten."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Aus diesem Dokument eine Vorlage erstellen."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit dem modernen Dokumentensign
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "Aktuelles Passwort ist falsch."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Aktuelle Empfänger:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Aktuelle Nutzung im Verhältnis zu den Organisationslimits."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Derzeit können alle Organisationsmitglieder auf dieses Team zugreifen"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "Datum"
|
|||
msgid "Date created"
|
||||
msgstr "Erstellungsdatum"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Datumsformat"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "Standardorganisation Rolle für neue Benutzer"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Standardempfänger"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Standardeinstellungen, die auf diese Organisation angewendet werden."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Standardeinstellungen, die auf dieses Team angewendet werden. Vererbte Werte stammen von der Organisation."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Standard-Signatureinstellungen"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "Standardwert"
|
|||
msgid "Default Value"
|
||||
msgstr "Standardwert"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Dokumenteneigentum delegieren"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Dokumenteigentum delegieren"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Deaktivieren Sie die Zwei-Faktor-Authentifizierung, bevor Sie Ihr Konto löschen."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "Dokument genehmigt"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Dokument storniert"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Dokument abgeschlossen"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "Dokument erstellt von <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Dokument erstellt aus direkter Vorlage"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Dokument erstellt aus direkter Vorlagen-E-Mail"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Dokument erstellt mit einem <0>direkten Link</0>"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "Dokumenterstellung"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Dokument gelöscht"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "Dokument ist bereits hochgeladen"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "Dokument verwendet Altfeld-Integration"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Dokumentensprache"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Dokumentenlimit überschritten!"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Dokument geöffnet"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Dokument ausstehend"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "Dokument abgelehnt"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Dokument Abgelehnt"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Dokument umbenannt"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Dokument gesendet"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "Der Dokumentenunterzeichnungsprozess wird abgebrochen"
|
|||
msgid "Document status"
|
||||
msgstr "Dokumentenstatus"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Dokumentenzeitzone"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Dokumenttitel"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "Dokument betrachtet"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Dokument angesehen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Zeichnen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Unterschrift zeichnen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "PDF hier ablegen oder klicken, um auszuwählen"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "Offenlegung der elektronischen Unterschrift"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "E-Mail bestätigt!"
|
|||
msgid "Email Created"
|
||||
msgstr "E-Mail erstellt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "E-Mail-Dokumenteinstellungen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "E-Mail-Domain"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "Empfänger per E-Mail benachrichtigen, wenn sie von einem ausstehenden D
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "Empfänger per E-Mail mit einer Signaturanfrage benachrichtigen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "E-Mail-Reply-To"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "E-Mail gesendet!"
|
|||
msgid "Email Settings"
|
||||
msgstr "E-Mail-Einstellungen"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Den Eigentümer per E-Mail benachrichtigen, wenn ein Dokument aus einer direkten Vorlage erstellt wird"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "Eigentümer per E-Mail benachrichtigen, wenn ein Empfänger unterschreibt"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "Team-API-Tokens aktivieren, um das Dokumenteigentum an ein anderes Teamm
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "Eingeben"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Geben Sie einen Namen für Ihren neuen Ordner ein. Ordner helfen Ihnen, Ihre Dateien zu organisieren."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Neuen Titel eingeben"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Anspruchsname eingeben"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "Feldschriftgröße"
|
|||
msgid "Field format"
|
||||
msgstr "Feldformat"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "Feld-ID:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Globale Empfängerauthentifizierung"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Globale Einstellungen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "Posteingang"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Posteingang Dokumente"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Prüfprotokoll einbeziehen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Felder einschließen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Empfänger einschließen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Absenderdetails einbeziehen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Signaturzertifikat einbeziehen"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Audit-Logs im Dokument einbeziehen"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "Von der Organisation erben"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Organisationsmitglieder erben"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Vererbt"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "Laden Sie Teammitglieder zur Zusammenarbeit ein"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Laden Sie sie zuerst in die Organisation ein"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Eingeladen"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Eingeladen am"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Treten Sie unserer Community auf <0>Discord</0> bei, um Unterstützung zu erhalten und sich auszutauschen."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Beigetreten"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "Beigetreten"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Beigetreten {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Zentrale Kennungen und Beziehungen für dieses Team."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Koreanisch"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "Verknüpfte Konten verwalten"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Organisation verwalten"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "Sitzungen verwalten"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Abonnement verwalten"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Team verwalten"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "Verwalten Sie die {0} Organisation"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Verwalten Sie das Abonnement der {0} Organisation"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Das Team {0} verwalten"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Verwalten Sie die benutzerdefinierten Gruppen von Mitgliedern für Ihre Organisation."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "Verwalten Sie hier Ihre Seiteneinstellungen"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "Maximale Anzahl hochgeladener Dateien pro Umschlag erlaubt"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "Mitglied seit"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "Mitglied seit"
|
|||
msgid "Members"
|
||||
msgstr "Mitglieder"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Mitglieder, die derzeit zu diesem Team gehören."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Nachricht"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "Nicht gefunden"
|
|||
msgid "Not Found"
|
||||
msgstr "Nicht gefunden"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "Nicht festgelegt"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Nicht unterstützt"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "Anzahl der erlaubten Teams. 0 = Unbegrenzt"
|
|||
msgid "Number Settings"
|
||||
msgstr "Zahleneinstellungen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Aus"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "Ein"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "Auf dieser Seite können Sie einen neuen Webhook erstellen."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "Einstellungen für Organisationsgruppen"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "Organisation wurde erfolgreich aktualisiert"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "Organisations-ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organisation nicht gefunden"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Organisationsrolle"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "Organisationsvorlagen werden mit allen Teams innerhalb derselben Organis
|
|||
msgid "Organisation URL"
|
||||
msgstr "Organisations-URL"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Organisationsnutzung"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Ausstehende Einladungen auf Organisationsebene für die übergeordnete Organisation dieses Teams."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "Organisationseinstellungen überschreiben"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "Organisationseinstellungen überschreiben"
|
|||
msgid "Owner"
|
||||
msgstr "Besitzer"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Dokument des Eigentümers abgeschlossen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Dokument des Eigentümers erstellt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Empfänger des Eigentümers abgelaufen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Eigentumsrechte wurden an {organisationMemberName} übertragen."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "Bei ausstehenden Dokumenten wird der Signaturvorgang abgebrochen"
|
|||
msgid "Pending invitations"
|
||||
msgstr "Ausstehende Einladungen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Ausstehende Organisationseinladungen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "Ausstehend seit"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "E-Mail über abgelaufenen Empfänger"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "Dem Empfänger ist es nicht gelungen, ein 2FA-Token für das Dokument zu verifizieren"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "Empfänger-ID:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "Der Empfänger hat das Dokument abgelehnt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Empfänger entfernt"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "E-Mail des entfernten Empfängers"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "E-Mail des entfernten Empfängers"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "Der Empfänger hat ein 2FA-Token für das Dokument angefordert"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Empfänger hat unterschrieben"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "E-Mail über Empfänger-unterschrieben"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "E-Mail über Empfänger-unterschrieben"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "Der Empfänger hat das Dokument unterschrieben"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Signaturanforderung für Empfänger"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "E-Mail zur Unterzeichnungsanfrage des Empfängers"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "Team-E-Mail entfernen"
|
|||
msgid "Remove team member"
|
||||
msgstr "Teammitglied entfernen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Umbenennen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Dokument umbenennen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Vorlage umbenennen"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "Rechts"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Rolle"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "Zeilen pro Seite"
|
|||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Als Vorlage speichern"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "Einige Unterzeichner haben noch kein Unterschriftsfeld zugewiesen bekomm
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "Etwas ist schiefgelaufen. Bitte versuchen Sie es später noch einmal."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Etwas ist schiefgelaufen. Bitte versuche es erneut."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Entschuldigung, wir konnten die Prüfprotokolle nicht herunterladen. Bitte versuchen Sie es später erneut."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "Teamzuweisungen"
|
|||
msgid "Team Count"
|
||||
msgstr "Teamanzahl"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Teamdetails"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "Team-E-Mail wurde entfernt"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "Team-E-Mail wurde für {0} widerrufen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Team-E-Mail-Name"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Team-E-Mail entfernt"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "Team-E-Mail wurde aktualisiert."
|
|||
msgid "Team Groups"
|
||||
msgstr "Teamgruppen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "Team-ID"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Team Manager"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "Team Manager"
|
|||
msgid "Team Member"
|
||||
msgstr "Teammitglied"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Teammitglieder"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "Teamname"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Team nicht gefunden"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "Nur Team"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Nur Teamvorlagen sind nirgendwo verlinkt und nur für Ihr Team sichtbar."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Teamrolle"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "Team-URL"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "Team-URL"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "Team-URL"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "Vorlage"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Vorlage (Legacy)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "Vorlage verwendet Altfeld-Integration"
|
|||
msgid "Template moved"
|
||||
msgstr "Vorlage verschoben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Vorlage umbenannt"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Vorlage gespeichert"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "Die Team-E-Mail <0>{teamEmail}</0> wurde aus dem folgenden Team entfernt"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "Das Team, das Sie suchen, wurde möglicherweise entfernt, umbenannt oder hat möglicherweise nie existiert."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "Dieses Dokument konnte derzeit nicht dupliziert werden. Bitte versuche e
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Dieses Dokument konnte zu diesem Zeitpunkt nicht erneut gesendet werden. Bitte versuchen Sie es erneut."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "Dieses Dokument konnte derzeit nicht als Vorlage gespeichert werden. Bitte versuchen Sie es erneut."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "Diese E-Mail bestätigt, dass Sie das Dokument <0>\"{documentName}\"</0>
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Diese E-Mail-Adresse wird bereits von einem anderen Team verwendet."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "Diese E-Mail wird an den Dokumenteigentümer gesendet, wenn ein Empfänger ein Dokument über einen direkten Vorlagenlink erstellt."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Diese E-Mail wird an den Dokumenteneigentümer gesendet, wenn ein Empfänger das Dokument unterschrieben hat."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "Zeitzone"
|
|||
msgid "Time Zone"
|
||||
msgstr "Zeitzone"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "Geben Sie eine E-Mail-Adresse ein, um einen Empfänger hinzuzufügen"
|
|||
msgid "Type your signature"
|
||||
msgstr "Geben Sie Ihre Unterschrift ein"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Getippte Unterschrift"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Getippte Unterschriften sind nicht erlaubt. Bitte zeichnen Sie Ihre Unterschrift."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "Unbekannter Name"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Unbegrenzt"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "Dokumente hochladen und Empfänger hinzufügen"
|
|||
msgid "Upload failed"
|
||||
msgstr "Hochladen fehlgeschlagen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Unterschrift hochladen"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Signatur hochladen"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "Benutzer-Agent"
|
|||
msgid "User has no password."
|
||||
msgstr "Benutzer hat kein Passwort."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "Benutzer-ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Benutzer nicht gefunden"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "Dein Dokument wurde von einem Administrator gelöscht!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Ihr Dokument wurde erfolgreich erneut gesendet."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Ihr Dokument wurde als Vorlage gespeichert."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Ihr Dokument wurde erfolgreich gesendet."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "Ihr Dokument wurde erfolgreich gesendet."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Ihr Dokument wurde erfolgreich dupliziert."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Dein Dokument wurde erfolgreich umbenannt."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Ihr Dokument wurde erfolgreich aktualisiert"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "Ihre Vorlage wurde erfolgreich dupliziert."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Ihre Vorlage wurde erfolgreich gelöscht."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Deine Vorlage wurde erfolgreich umbenannt."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Ihre Vorlage wurde erfolgreich aktualisiert"
|
||||
|
|
|
|||
|
|
@ -847,6 +847,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Profile not found"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Team not found"
|
||||
|
|
@ -1010,6 +1012,10 @@ msgstr "A unique URL to identify your organisation"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "A unique URL to identify your team"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "A valid email is required"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "A verification email will be sent to the provided email."
|
||||
|
|
@ -1386,6 +1392,7 @@ msgstr "Additional brand information to display at the bottom of emails"
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1434,6 +1441,10 @@ msgstr "After signing a document electronically, you will be provided the opport
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "AI features"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "AI Features"
|
||||
|
|
@ -2204,12 +2215,21 @@ msgstr "Brand Details"
|
|||
msgid "Brand Website"
|
||||
msgstr "Brand Website"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Branding company details"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Branding logo"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Branding Logo"
|
||||
|
|
@ -2228,6 +2248,10 @@ msgstr "Branding Preferences"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Branding preferences updated"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "Branding URL"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2325,6 +2349,8 @@ msgstr "Can't find someone?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2876,8 +2902,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Controls how long recipients have to complete signing before the document expires. After expiration, recipients can no longer sign the document."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Controls the default email settings when new documents or templates are created"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2939,6 +2965,7 @@ msgstr "Copied field to clipboard"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2955,6 +2982,10 @@ msgstr "Copy"
|
|||
msgid "Copy Link"
|
||||
msgstr "Copy Link"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Copy organisation ID"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Copy sharable link"
|
||||
|
|
@ -2968,6 +2999,10 @@ msgstr "Copy Shareable Link"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Copy Signing Links"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Copy team ID"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Copy token"
|
||||
|
|
@ -3010,6 +3045,10 @@ msgstr "Create a support ticket"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Create a team to collaborate with your team members."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Create a template from this document."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3187,6 +3226,8 @@ msgstr "Create your account and start using state-of-the-art document signing. O
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3242,6 +3283,10 @@ msgstr "Current password is incorrect."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Current recipients:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Current usage against organisation limits."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Currently all organisation members can access this team"
|
||||
|
|
@ -3291,6 +3336,10 @@ msgstr "Date"
|
|||
msgid "Date created"
|
||||
msgstr "Date created"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Date format"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3348,6 +3397,14 @@ msgstr "Default Organisation Role for New Users"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Default Recipients"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Default settings applied to this organisation."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Default settings applied to this team. Inherited values come from the organisation."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Default Signature Settings"
|
||||
|
|
@ -3367,6 +3424,10 @@ msgstr "Default value"
|
|||
msgid "Default Value"
|
||||
msgstr "Default Value"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Delegate document ownership"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Delegate Document Ownership"
|
||||
|
|
@ -3702,6 +3763,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Disable Two Factor Authentication before deleting your account."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3821,6 +3883,7 @@ msgstr "Document Approved"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Document Cancelled"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Document completed"
|
||||
|
|
@ -3865,6 +3928,10 @@ msgstr "Document created by <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Document created from direct template"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Document created from direct template email"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Document created using a <0>direct link</0>"
|
||||
|
|
@ -3876,6 +3943,7 @@ msgstr "Document Creation"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Document deleted"
|
||||
|
|
@ -3942,6 +4010,10 @@ msgstr "Document is already uploaded"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "Document is using legacy field insertion"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Document language"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Document Limit Exceeded!"
|
||||
|
|
@ -3968,6 +4040,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Document opened"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Document pending"
|
||||
|
|
@ -4004,6 +4077,10 @@ msgstr "Document rejected"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Document Rejected"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Document Renamed"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Document sent"
|
||||
|
|
@ -4036,6 +4113,10 @@ msgstr "Document signing process will be cancelled"
|
|||
msgid "Document status"
|
||||
msgstr "Document status"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Document timezone"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Document title"
|
||||
|
|
@ -4085,6 +4166,7 @@ msgstr "Document viewed"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Document Viewed"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4274,6 +4356,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Draw"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Draw signature"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "Drop PDF here or click to select"
|
||||
|
|
@ -4422,7 +4508,7 @@ msgstr "Electronic Signature Disclosure"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4471,6 +4557,10 @@ msgstr "Email Confirmed!"
|
|||
msgid "Email Created"
|
||||
msgstr "Email Created"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "Email document settings"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "Email Domain"
|
||||
|
|
@ -4532,6 +4622,10 @@ msgstr "Email recipients when they're removed from a pending document"
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "Email recipients with a signing request"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "Email reply-to"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4557,6 +4651,10 @@ msgstr "Email sent!"
|
|||
msgid "Email Settings"
|
||||
msgstr "Email Settings"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Email the owner when a document is created from a direct template"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "Email the owner when a recipient signs"
|
||||
|
|
@ -4674,6 +4772,7 @@ msgstr "Enable team API tokens to delegate document ownership to another team me
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4712,6 +4811,10 @@ msgstr "Enter"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Enter a name for your new folder. Folders help you organise your items."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Enter a new title"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Enter claim name"
|
||||
|
|
@ -5169,6 +5272,11 @@ msgstr "Field font size"
|
|||
msgid "Field format"
|
||||
msgstr "Field format"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "Field ID:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5366,6 +5474,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Global recipient action authentication"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Global Settings"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5692,6 +5807,26 @@ msgstr "Inbox"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Inbox documents"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Include audit log"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Include Fields"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Include Recipients"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Include sender details"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Include signing certificate"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Include the Audit Logs in the Document"
|
||||
|
|
@ -5735,6 +5870,10 @@ msgstr "Inherit from organisation"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Inherit organisation members"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Inherited"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5860,6 +5999,10 @@ msgstr "Invite team members to collaborate"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Invite them to the organisation first"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Invited"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Invited At"
|
||||
|
|
@ -5929,6 +6072,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Join our community on <0>Discord</0> for community support and discussion."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Joined"
|
||||
|
||||
|
|
@ -5937,6 +6082,10 @@ msgstr "Joined"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Joined {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Key identifiers and relationships for this team."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Korean"
|
||||
|
|
@ -6247,6 +6396,7 @@ msgstr "Manage linked accounts"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Manage organisation"
|
||||
|
||||
|
|
@ -6276,6 +6426,10 @@ msgstr "Manage sessions"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Manage subscription"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Manage team"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6286,6 +6440,11 @@ msgstr "Manage the {0} organisation"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Manage the {0} organisation subscription"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Manage the {0} team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Manage the custom groups of members for your organisation."
|
||||
|
|
@ -6336,6 +6495,7 @@ msgstr "Manage your site settings here"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6391,6 +6551,8 @@ msgstr "Maximum number of uploaded files per envelope allowed"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6412,6 +6574,8 @@ msgstr "Member Since"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6419,6 +6583,10 @@ msgstr "Member Since"
|
|||
msgid "Members"
|
||||
msgstr "Members"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Members that currently belong to this team."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Message"
|
||||
|
|
@ -6849,6 +7017,10 @@ msgstr "Not found"
|
|||
msgid "Not Found"
|
||||
msgstr "Not Found"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "Not set"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Not supported"
|
||||
|
|
@ -6891,6 +7063,14 @@ msgstr "Number of teams allowed. 0 = Unlimited"
|
|||
msgid "Number Settings"
|
||||
msgstr "Number Settings"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Off"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "On"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "On this page, you can create a new webhook."
|
||||
|
|
@ -7029,6 +7209,10 @@ msgstr "Organisation Group Settings"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "Organisation has been updated successfully"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "Organisation ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7071,6 +7255,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organisation not found"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Organisation role"
|
||||
|
||||
|
|
@ -7110,6 +7295,14 @@ msgstr "Organisation templates are shared across all teams within the same organ
|
|||
msgid "Organisation URL"
|
||||
msgstr "Organisation URL"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Organisation usage"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Organisation-level pending invites for this team's parent organisation."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7161,6 +7354,7 @@ msgstr "Override organisation settings"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7169,6 +7363,18 @@ msgstr "Override organisation settings"
|
|||
msgid "Owner"
|
||||
msgstr "Owner"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Owner document completed"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Owner document created"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Owner recipient expired"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Ownership transferred to {organisationMemberName}."
|
||||
|
|
@ -7320,6 +7526,10 @@ msgstr "Pending documents will have their signing process cancelled"
|
|||
msgid "Pending invitations"
|
||||
msgstr "Pending invitations"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Pending Organisation Invites"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "Pending since"
|
||||
|
|
@ -7888,10 +8098,19 @@ msgstr "Recipient expired email"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "Recipient failed to validate a 2FA token for the document"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "Recipient ID:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "Recipient rejected the document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Recipient removed"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "Recipient removed email"
|
||||
|
|
@ -7900,6 +8119,10 @@ msgstr "Recipient removed email"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "Recipient requested a 2FA token for the document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Recipient signed"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "Recipient signed email"
|
||||
|
|
@ -7908,6 +8131,10 @@ msgstr "Recipient signed email"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "Recipient signed the document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Recipient signing request"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "Recipient signing request email"
|
||||
|
|
@ -8110,6 +8337,21 @@ msgstr "Remove team email"
|
|||
msgid "Remove team member"
|
||||
msgstr "Remove team member"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Rename"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Rename Document"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Rename Template"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8360,6 +8602,8 @@ msgstr "Right"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Role"
|
||||
|
||||
|
|
@ -8381,6 +8625,15 @@ msgstr "Rows per page"
|
|||
msgid "Save"
|
||||
msgstr "Save"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Save as Template"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9155,6 +9408,7 @@ msgstr "Some signers have not been assigned a signature field. Please assign at
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9268,6 +9522,10 @@ msgstr "Something went wrong. Please try again later."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Something went wrong. Please try again or contact support."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Something went wrong. Please try again."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
|
|
@ -9552,6 +9810,11 @@ msgstr "Team Assignments"
|
|||
msgid "Team Count"
|
||||
msgstr "Team Count"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Team details"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9574,6 +9837,10 @@ msgstr "Team email has been removed"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "Team email has been revoked for {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Team email name"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Team email removed"
|
||||
|
|
@ -9598,6 +9865,11 @@ msgstr "Team email was updated."
|
|||
msgid "Team Groups"
|
||||
msgstr "Team Groups"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "Team ID"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Team Manager"
|
||||
|
|
@ -9607,6 +9879,7 @@ msgstr "Team Manager"
|
|||
msgid "Team Member"
|
||||
msgstr "Team Member"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Team Members"
|
||||
|
|
@ -9627,6 +9900,8 @@ msgid "Team Name"
|
|||
msgstr "Team Name"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Team not found"
|
||||
|
|
@ -9639,6 +9914,10 @@ msgstr "Team Only"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Team only templates are not linked anywhere and are visible only to your team."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Team role"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9660,6 +9939,7 @@ msgstr "Team url"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "Team URL"
|
||||
|
||||
|
|
@ -9667,6 +9947,7 @@ msgstr "Team URL"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9699,6 +9980,7 @@ msgstr "Template"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Template (Legacy)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9740,6 +10022,10 @@ msgstr "Template is using legacy field insertion"
|
|||
msgid "Template moved"
|
||||
msgstr "Template moved"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Template Renamed"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Template saved"
|
||||
|
|
@ -10152,6 +10438,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "The team email <0>{teamEmail}</0> has been removed from the following team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
|
|
@ -10322,6 +10610,10 @@ msgstr "This document could not be duplicated at this time. Please try again."
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "This document could not be re-sent at this time. Please try again."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "This document could not be saved as a template at this time. Please try again."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10380,6 +10672,10 @@ msgstr "This email confirms that you have rejected the document <0>\"{documentNa
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "This email is already being used by another team."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "This email is sent to the document owner when a recipient has signed the document."
|
||||
|
|
@ -10557,6 +10853,7 @@ msgstr "Time zone"
|
|||
msgid "Time Zone"
|
||||
msgstr "Time Zone"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10857,6 +11154,10 @@ msgstr "Type an email address to add a recipient"
|
|||
msgid "Type your signature"
|
||||
msgstr "Type your signature"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Typed signature"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Typed signatures are not allowed. Please draw your signature."
|
||||
|
|
@ -10985,6 +11286,8 @@ msgid "Unknown name"
|
|||
msgstr "Unknown name"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Unlimited"
|
||||
|
||||
|
|
@ -11230,6 +11533,10 @@ msgstr "Upload documents and add recipients"
|
|||
msgid "Upload failed"
|
||||
msgstr "Upload failed"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Upload signature"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Upload Signature"
|
||||
|
|
@ -11317,6 +11624,11 @@ msgstr "User Agent"
|
|||
msgid "User has no password."
|
||||
msgstr "User has no password."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "User ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "User not found"
|
||||
|
|
@ -13002,6 +13314,10 @@ msgstr "Your document has been deleted by an admin!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Your document has been re-sent successfully."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Your document has been saved as a template."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Your document has been sent successfully."
|
||||
|
|
@ -13010,6 +13326,10 @@ msgstr "Your document has been sent successfully."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Your document has been successfully duplicated."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Your document has been successfully renamed."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Your document has been updated successfully"
|
||||
|
|
@ -13177,6 +13497,10 @@ msgstr "Your template has been duplicated successfully."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Your template has been successfully deleted."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Your template has been successfully renamed."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Your template has been updated successfully"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: es\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Perfil no encontrado"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Equipo no encontrado"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "Una URL única para identificar tu organización"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Una URL única para identificar tu equipo"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "Se requiere un correo electrónico válido"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Se enviará un correo electrónico de verificación a la dirección proporcionada."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "Información adicional de la marca para mostrar al final de los correos
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "Después de firmar un documento electrónicamente, se le dará la oportu
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Después de la presentación, se generará automáticamente un documento y se agregará a su página de documentos. También recibirá una notificación por correo electrónico."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "Funciones de IA"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "Funciones de IA"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "Detalles de la Marca"
|
|||
msgid "Brand Website"
|
||||
msgstr "Sitio Web de la Marca"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Detalles de la empresa para la marca"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Logotipo de la marca"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Logotipo de Marca"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "Preferencias de marca"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Preferencias de marca actualizadas"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "URL de la marca"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "¿No puedes encontrar a alguien?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Controla cuánto tiempo tienen los destinatarios para completar la firma antes de que el documento caduque. Después de la caducidad, los destinatarios ya no podrán firmar el documento."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Controla la configuración de correo electrónico predeterminada cuando se crean nuevos documentos o plantillas"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Controla la configuración de correo electrónico predeterminada cuando se crean nuevos documentos o plantillas. Actualizar esta configuración no afectará a los documentos o plantillas existentes."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "Campo copiado al portapapeles"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "Copiar"
|
|||
msgid "Copy Link"
|
||||
msgstr "Copiar enlace"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Copiar ID de la organización"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Copiar enlace compartible"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "Copiar enlace compartible"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Copiar enlaces de firma"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Copiar ID del equipo"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Copiar token"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "Crea un ticket de soporte"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Crea un equipo para colaborar con los miembros de tu equipo."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Crear una plantilla a partir de este documento."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "Crea tu cuenta y comienza a utilizar la firma de documentos de última g
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "La contraseña actual es incorrecta."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Destinatarios actuales:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Uso actual frente a los límites de la organización."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Actualmente, todos los miembros de la organización pueden acceder a este equipo"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "Fecha"
|
|||
msgid "Date created"
|
||||
msgstr "Fecha de creación"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Formato de fecha"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "Rol de organización predeterminado para nuevos usuarios"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Destinatarios predeterminados"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Configuración predeterminada aplicada a esta organización."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Configuración predeterminada aplicada a este equipo. Los valores heredados provienen de la organización."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Configuraciones de Firma por Defecto"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "Valor predeterminado"
|
|||
msgid "Default Value"
|
||||
msgstr "Valor Predeterminado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Delegar la propiedad del documento"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Delegar la propiedad del documento"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Deshabilite la Autenticación de Dos Factores antes de eliminar su cuenta."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "Documento Aprobado"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Documento cancelado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Documento completado"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "Documento creado por <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Documento creado a partir de plantilla directa"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Documento creado a partir de un correo electrónico de plantilla directa"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Documento creado usando un <0>enlace directo</0>"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "Creación de documento"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Documento eliminado"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "El documento ya está cargado"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "El documento utiliza inserción de campos heredada"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Idioma del documento"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "¡Límite de documentos excedido!"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Documento abierto"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Documento pendiente"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "Documento rechazado"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Documento Rechazado"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Documento renombrado"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Documento enviado"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "El proceso de firma del documento será cancelado"
|
|||
msgid "Document status"
|
||||
msgstr "Estado del documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Zona horaria del documento"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Título del documento"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "Documento visto"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Documento visto"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Dibujar"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Dibujar firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "Suelta el PDF aquí o haz clic para seleccionarlo"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "Divulgación de Firma Electrónica"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "¡Correo electrónico confirmado!"
|
|||
msgid "Email Created"
|
||||
msgstr "Correo creado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "Configuración del documento por correo electrónico"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "Dominio de correo electrónico"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "Enviar un correo electrónico a los destinatarios cuando se les elimine
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "Enviar un correo electrónico a los destinatarios con una solicitud de firma"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "Dirección de respuesta del correo electrónico"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "¡Correo electrónico enviado!"
|
|||
msgid "Email Settings"
|
||||
msgstr "Configuración de Correo Electrónico"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Enviar un correo electrónico al propietario cuando se cree un documento a partir de una plantilla directa"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "Enviar un correo electrónico al propietario cuando un destinatario firme"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "Habilita los tokens de API del equipo para delegar la propiedad del docu
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "Ingresar"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Ingrese un nombre para su nueva carpeta. Las carpetas le ayudan a organizar sus elementos."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Introduce un nuevo título"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Ingresar nombre de la reclamación"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "Tamaño de fuente del campo"
|
|||
msgid "Field format"
|
||||
msgstr "Formato de campo"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "ID de campo:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Autenticación de acción de destinatario global"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Configuración global"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "Bandeja de entrada"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Documentos en bandeja de entrada"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Incluir registro de auditoría"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Incluir campos"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Incluir destinatarios"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Incluir datos del remitente"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Incluir certificado de firma"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Incluir los registros de auditoría en el documento"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "Heredar de la organización"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Heredar miembros de la organización"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Heredado"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "Invitar miembros del equipo a colaborar"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Invítalos primero a la organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Invitado"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Invitado el"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Únete a nuestra comunidad en <0>Discord</0> para soporte y debate."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Unido"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "Unido"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Se unió a {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Identificadores clave y relaciones para este equipo."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Coreano"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "Gestionar cuentas vinculadas"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Administrar organización"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "Gestionar sesiones"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Gestionar suscripción"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Gestionar equipo"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "Gestionar la organización {0}"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Gestionar la suscripción de la organización {0}"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Gestionar el equipo {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Gestiona los grupos personalizados de miembros para tu organización."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "Gestionar la configuración de tu sitio aquí"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "Número máximo de archivos subidos por sobre permitido"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "Miembro desde"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "Miembro desde"
|
|||
msgid "Members"
|
||||
msgstr "Miembros"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Miembros que pertenecen actualmente a este equipo."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Mensaje"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "No Encontrado"
|
|||
msgid "Not Found"
|
||||
msgstr "No encontrado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "No establecido"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "No soportado"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "Número de equipos permitidos. 0 = Ilimitado"
|
|||
msgid "Number Settings"
|
||||
msgstr "Configuración de Número"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Desactivado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "Activado"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "En esta página, puedes crear un nuevo webhook."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "Configuración de Grupo de Organización"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "La organización ha sido actualizada con éxito"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "ID de la organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organización no encontrada"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Rol de organización"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "Las plantillas de organización se comparten entre todos los equipos de
|
|||
msgid "Organisation URL"
|
||||
msgstr "URL de Organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Uso de la organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Invitaciones pendientes a nivel de organización para la organización principal de este equipo."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "Anular la configuración de la organización"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "Anular la configuración de la organización"
|
|||
msgid "Owner"
|
||||
msgstr "Propietario"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Documento del propietario completado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Documento del propietario creado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Destinatario del propietario caducado"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Propiedad transferida a {organisationMemberName}."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "Los documentos pendientes cancelarán su proceso de firma"
|
|||
msgid "Pending invitations"
|
||||
msgstr "Invitaciones pendientes"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Invitaciones pendientes de la organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "Pendiente desde"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "Correo electrónico de destinatario vencido"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "El destinatario no pudo validar un token 2FA para el documento"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "ID de destinatario:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "El destinatario rechazó el documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Destinatario eliminado"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "Correo electrónico de destinatario eliminado"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "Correo electrónico de destinatario eliminado"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "El destinatario solicitó un token 2FA para el documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Destinatario firmó"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "Correo electrónico de destinatario firmado"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "Correo electrónico de destinatario firmado"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "El destinatario firmó el documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Solicitud de firma del destinatario"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "Correo electrónico de solicitud de firma de destinatario"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "Eliminar correo electrónico del equipo"
|
|||
msgid "Remove team member"
|
||||
msgstr "Eliminar miembro del equipo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Renombrar"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Renombrar documento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Renombrar plantilla"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "Derecha"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Rol"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "Filas por página"
|
|||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Guardar como plantilla"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "Algunos firmantes no han sido asignados a un campo de firma. Asigne al m
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "Algo salió mal. Por favor, inténtelo de nuevo más tarde."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Algo salió mal. Por favor, intenta de nuevo o contacta al soporte."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Algo salió mal. Vuelve a intentarlo."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Lo sentimos, no pudimos descargar los registros de auditoría. Por favor, intenta de nuevo más tarde."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "Asignaciones de equipo"
|
|||
msgid "Team Count"
|
||||
msgstr "Conteo de equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Detalles del equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "El correo del equipo ha sido eliminado"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "El correo electrónico del equipo ha sido revocado para {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Nombre del correo electrónico del equipo"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Correo electrónico del equipo eliminado"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "El correo del equipo ha sido actualizado."
|
|||
msgid "Team Groups"
|
||||
msgstr "Grupos de equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "ID del equipo"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Gerente de equipo"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "Gerente de equipo"
|
|||
msgid "Team Member"
|
||||
msgstr "Miembro del equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Miembros del equipo"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "Nombre del equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Equipo no encontrado"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "Solo equipo"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Las plantillas solo para el equipo no están vinculadas en ningún lado y son visibles solo para tu equipo."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Rol del equipo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "URL del equipo"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "URL del equipo"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "URL del equipo"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "Plantilla"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Plantilla (Legado)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "La plantilla utiliza inserción de campos heredada"
|
|||
msgid "Template moved"
|
||||
msgstr "Plantilla movida"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Plantilla renombrada"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Plantilla guardada"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "El correo electrónico del equipo <0>{teamEmail}</0> ha sido eliminado del siguiente equipo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "El equipo que estás buscando puede haber sido eliminado, renombrado o quizás nunca existió."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "Este documento no se pudo duplicar en este momento. Por favor, inténtal
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Este documento no se pudo reenviar en este momento. Por favor, inténtalo de nuevo."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "Este documento no se pudo guardar como plantilla en este momento. Por favor, inténtelo de nuevo."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "Este correo electrónico confirma que ha rechazado el documento <0>\"{do
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Este correo electrónico ya está siendo utilizado por otro equipo."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "Este correo electrónico se envía al propietario del documento cuando un destinatario crea un documento mediante un enlace de plantilla directa."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Este correo electrónico se envía al propietario del documento cuando un destinatario ha firmado el documento."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "Zona horaria"
|
|||
msgid "Time Zone"
|
||||
msgstr "Zona horaria"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "Escribe una dirección de correo electrónico para agregar un destinatar
|
|||
msgid "Type your signature"
|
||||
msgstr "Escribe tu firma"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Firma escrita a máquina"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "No se permiten firmas mecanografiadas. Por favor, dibuje su firma."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "Nombre desconocido"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Ilimitado"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "Suba documentos y añada destinatarios"
|
|||
msgid "Upload failed"
|
||||
msgstr "Subida fallida"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Cargar firma"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Subir firma"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "Agente de usuario"
|
|||
msgid "User has no password."
|
||||
msgstr "El usuario no tiene contraseña."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "ID de usuario"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Usuario no encontrado"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "¡Tu documento ha sido eliminado por un administrador!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Tu documento ha sido reenviado con éxito."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Tu documento se ha guardado como plantilla."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Tu documento ha sido enviado con éxito."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "Tu documento ha sido enviado con éxito."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Tu documento ha sido duplicado con éxito."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Tu documento se ha renombrado correctamente."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Tu documento se ha actualizado correctamente"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "Tu plantilla ha sido duplicada con éxito."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Tu plantilla ha sido eliminada con éxito."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Tu plantilla se ha renombrado correctamente."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Tu plantilla se ha actualizado correctamente"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: fr\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Profil non trouvé"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Équipe non trouvée"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "Une URL unique pour identifier votre organisation"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Une URL unique pour identifier votre équipe"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "Une adresse e-mail valide est requise"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Un e-mail de vérification sera envoyé à l'adresse e-mail fournie."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "Informations supplémentaires sur la marque à afficher en bas des e-mai
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "Après avoir signé un document électroniquement, vous aurez l'occasion
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Après soumission, un document sera automatiquement généré et ajouté à votre page de documents. Vous recevrez également une notification par e-mail."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "Fonctionnalités d’IA"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "Fonctionnalités IA"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "Détails de la marque"
|
|||
msgid "Brand Website"
|
||||
msgstr "Site web de la marque"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Image de marque"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Informations sur l’entreprise pour l’image de marque"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Logo de l’image de marque"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Logo de la marque"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "Préférences de branding"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Préférences de branding mises à jour"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "URL de l’image de marque"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "Vous ne trouvez pas quelqu’un ?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Détermine combien de temps les destinataires disposent pour terminer la signature avant l’expiration du document. Après expiration, les destinataires ne peuvent plus signer le document."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Contrôler les paramètres de messagerie par défaut lors de la création de nouveaux documents ou modèles"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Contrôle les paramètres d’e-mail par défaut lorsque de nouveaux documents ou modèles sont créés. La mise à jour de ces paramètres n’affectera pas les documents ou modèles existants."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "Champ copié dans le presse-papiers"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "Copier"
|
|||
msgid "Copy Link"
|
||||
msgstr "Copier le lien"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Copier l’ID de l’organisation"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Copier le lien partageable"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "Copier le lien partageable"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Copier les liens de signature"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Copier l’ID de l’équipe"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Copier le token"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "Créer un ticket de support"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Créer une équipe pour collaborer avec vos membres."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Créer un modèle à partir de ce document."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "Créez votre compte et commencez à utiliser la signature de documents
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "Le mot de passe actuel est incorrect."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Destinataires actuels :"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Utilisation actuelle par rapport aux limites de l’organisation."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Actuellement, tous les membres de l'organisation peuvent accéder à cette équipe"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "Date"
|
|||
msgid "Date created"
|
||||
msgstr "Date de création"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Format de date"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "Rôle par défaut de l'organisation pour les nouveaux utilisateurs"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Destinataires par défaut"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Paramètres par défaut appliqués à cette organisation."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Paramètres par défaut appliqués à cette équipe. Les valeurs héritées proviennent de l’organisation."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Paramètres de Signature par Défaut"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "Valeur par défaut"
|
|||
msgid "Default Value"
|
||||
msgstr "Valeur par défaut"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Déléguer la propriété du document"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Déléguer la propriété du document"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Désactiver l'authentification à deux facteurs avant de supprimer votre compte."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "Document Approuvé"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Document Annulé"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Document terminé"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "Document créé par <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Document créé à partir d'un modèle direct"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Document créé à partir d’un e-mail de modèle direct"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Document créé en utilisant un <0>lien direct</0>"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "Création de document"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Document supprimé"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "Document déjà importé"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "Le document utilise l'insertion de champ héritée"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Langue du document"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Limite de documents dépassée !"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Document ouvert"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Document en attente"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "Document rejeté"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Document Rejeté"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Document renommé"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Document envoyé"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "Le processus de signature du document sera annulé"
|
|||
msgid "Document status"
|
||||
msgstr "Statut du document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Fuseau horaire du document"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Titre du document"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "Document vu"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Document consulté"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Dessiner"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Dessiner la signature"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "Déposez le PDF ici ou cliquez pour en sélectionner un"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "Divulgation de signature électronique"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "Email confirmé !"
|
|||
msgid "Email Created"
|
||||
msgstr "E-mail créé"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "Paramètres d’email du document"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "Domaine e-mail"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "Envoyer un e-mail aux destinataires lorsqu’ils sont retirés d’un do
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "Envoyer un e-mail aux destinataires avec une demande de signature"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "Adresse de réponse de l’email"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "Email envoyé !"
|
|||
msgid "Email Settings"
|
||||
msgstr "Paramètres de l'email"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Envoyer un e-mail au propriétaire lorsqu’un document est créé à partir d’un modèle direct"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "Envoyer un e-mail au propriétaire lorsqu’un destinataire signe"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "Activer les jetons d’API d’équipe pour déléguer la propriété du
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "Entrer"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Entrez un nom pour votre nouveau dossier. Les dossiers vous aident à organiser vos éléments."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Saisissez un nouveau titre"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Entrez le nom de la réclamation"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "Taille de police du champ"
|
|||
msgid "Field format"
|
||||
msgstr "Format du champ"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "ID du champ :"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Authentification d'action de destinataire globale"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Paramètres globaux"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "Boîte de réception"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Documents de la boîte de réception"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Inclure le journal d’audit"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Inclure les champs"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Inclure les destinataires"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Inclure les informations sur l’expéditeur"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Inclure le certificat de signature"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Inclure les journaux d'audit dans le document"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "Hériter de l'organisation"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Hériter des membres de l'organisation"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Hérité"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "Inviter des membres de l'équipe à collaborer"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Invitez‑les d’abord dans l’organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Invité"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Invité à"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Rejoignez notre communauté sur <0>Discord</0> pour obtenir de l'aide et discuter."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Joint"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "Joint"
|
|||
msgid "Joined {0}"
|
||||
msgstr "A rejoint {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Identifiants clés et relations pour cette équipe."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Coréen"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "Gérer les comptes liés"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Gérer l'organisation"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "Gérer les sessions"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Gérer l'abonnement"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Gérer l’équipe"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "Gérer l'organisation {0}"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Gérer l'abonnement de l'organisation {0}"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Gérer l’équipe {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Gérez les groupes personnalisés de membres pour votre organisation."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "Gérer les paramètres de votre site ici"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "Nombre maximal de fichiers téléchargés par enveloppe autorisés"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "Membre depuis"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "Membre depuis"
|
|||
msgid "Members"
|
||||
msgstr "Membres"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Membres qui appartiennent actuellement à cette équipe."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Message"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "Non trouvé"
|
|||
msgid "Not Found"
|
||||
msgstr "Introuvable"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "Non défini"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Non pris en charge"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "Nombre d'équipes autorisées. 0 = Illimité"
|
|||
msgid "Number Settings"
|
||||
msgstr "Paramètres du nombre"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Désactivé"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "Activé"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "Sur cette page, vous pouvez créer un nouveau webhook."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "Paramètres du groupe d'organisation"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "L'organisation a été mise à jour avec succès"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "ID d’organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organisation introuvable"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Rôle de l'organisation"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "Les modèles d’organisation sont partagés entre toutes les équipes d
|
|||
msgid "Organisation URL"
|
||||
msgstr "URL de l'organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Utilisation de l’organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Invitations en attente au niveau de l’organisation parente de cette équipe."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "Ignorer les paramètres de l'organisation"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "Ignorer les paramètres de l'organisation"
|
|||
msgid "Owner"
|
||||
msgstr "Propriétaire"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Document du propriétaire terminé"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Document du propriétaire créé"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Destinataire du propriétaire arrivé à expiration"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Propriété transférée à {organisationMemberName}."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "Les documents en attente verront leur processus de signature annulé"
|
|||
msgid "Pending invitations"
|
||||
msgstr "Invitations en attente"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Invitations à l’organisation en attente"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "En attente depuis"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "E-mail de destinataire expiré"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "Le destinataire n'a pas réussi à valider un jeton 2FA pour le document"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "ID du destinataire :"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "Le destinataire a rejeté le document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Destinataire supprimé"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "E-mail de destinataire supprimé"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "E-mail de destinataire supprimé"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "Le destinataire a demandé un jeton 2FA pour le document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Destinataire ayant signé"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "E-mail signé par le destinataire"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "E-mail signé par le destinataire"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "Le destinataire a signé le document"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Demande de signature au destinataire"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "E-mail de demande de signature de destinataire"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "Supprimer l'adresse e-mail de l'équipe"
|
|||
msgid "Remove team member"
|
||||
msgstr "Supprimer le membre de l'équipe"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Renommer"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Renommer le document"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Renommer le modèle"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "Droit"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Rôle"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "Lignes par page"
|
|||
msgid "Save"
|
||||
msgstr "Sauvegarder"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Enregistrer comme modèle"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "Certains signataires n'ont pas été assignés à un champ de signature.
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "Quelque chose a mal tourné. Veuillez réessayer plus tard."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Quelque chose a mal tourné. Veuillez réessayer ou contacter le support."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Une erreur s’est produite. Veuillez réessayer."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Désolé, nous n'avons pas pu télécharger les journaux d'audit. Veuillez réessayer plus tard."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "Affectations de l'équipe"
|
|||
msgid "Team Count"
|
||||
msgstr "Nombre d'équipes"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Détails de l’équipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "L'adresse e-mail de l'équipe a été supprimée"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "L'email d'équipe a été révoqué pour {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Nom d’email de l’équipe"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Email d'équipe supprimé"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "L'e-mail de l'équipe a été mis à jour."
|
|||
msgid "Team Groups"
|
||||
msgstr "Groupes de l'équipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "ID d’équipe"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Gestionnaire d'équipe"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "Gestionnaire d'équipe"
|
|||
msgid "Team Member"
|
||||
msgstr "Membre de l'équipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Membres de l'équipe"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "Nom de l'équipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Équipe introuvable"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "Équipe uniquement"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Les modèles uniquement pour l'équipe ne sont liés nulle part et ne sont visibles que pour votre équipe."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Rôle dans l’équipe"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "URL de l'équipe"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "URL de l'équipe"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "URL de l'équipe"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "Modèle"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Modèle (Legacy)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "Le modèle utilise l'insertion de champ héritée"
|
|||
msgid "Template moved"
|
||||
msgstr "Modèle déplacé"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Modèle renommé"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Modèle enregistré"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "L'email d'équipe <0>{teamEmail}</0> a été supprimé de l'équipe suivante"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "L'équipe que vous recherchez a peut-être été supprimée, renommée ou n'a jamais existé."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "Ce document n'a pas pu être dupliqué pour le moment. Veuillez réessay
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Ce document n'a pas pu être renvoyé pour le moment. Veuillez réessayer."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "Ce document n'a pas pu être enregistré comme modèle pour le moment. Veuillez réessayer."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "Cet e-mail confirme que vous avez rejeté le document <0>\"{documentName
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Cet e-mail est déjà utilisé par une autre équipe."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "Cet e-mail est envoyé au propriétaire du document lorsqu’un signataire crée un document via un lien de modèle direct."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Cet e-mail est envoyé au propriétaire du document lorsqu'un destinataire a signé le document."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "Fuseau horaire"
|
|||
msgid "Time Zone"
|
||||
msgstr "Fuseau horaire"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "Saisissez une adresse e-mail pour ajouter un destinataire"
|
|||
msgid "Type your signature"
|
||||
msgstr "Saisissez votre signature"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Signature tapée"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Les signatures dactylographiées ne sont pas autorisées. Veuillez dessiner votre signature."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "Nom inconnu"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Illimité"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "Importer des documents et ajouter des destinataires"
|
|||
msgid "Upload failed"
|
||||
msgstr "Échec de l'importation"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Téléverser une signature"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Importer une signature"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "Agent utilisateur"
|
|||
msgid "User has no password."
|
||||
msgstr "L'utilisateur n'a pas de mot de passe."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "ID utilisateur"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Utilisateur non trouvé"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "Votre document a été supprimé par un administrateur !"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Votre document a été renvoyé avec succès."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Votre document a été enregistré comme modèle."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Votre document a été envoyé avec succès."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "Votre document a été envoyé avec succès."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Votre document a été dupliqué avec succès."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Votre document a été renommé avec succès."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Votre document a été mis à jour avec succès"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "Votre modèle a été dupliqué avec succès."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Votre modèle a été supprimé avec succès."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Votre modèle a été renommé avec succès."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Votre modèle a été mis à jour avec succès"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: it\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Profilo non trovato"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Squadra non trovata"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "Un URL unico per identificare la tua organizzazione"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Un URL univoco per identificare la tua squadra"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "È richiesta un'email valida"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Un'email di verifica sarà inviata all'email fornita."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "Informazioni aggiuntive sul marchio da mostrare in fondo alle email"
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "Dopo aver firmato un documento elettronicamente, avrai la possibilità d
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Dopo l'invio, un documento verrà generato automaticamente e aggiunto alla tua pagina dei documenti. Riceverai anche una notifica via email."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "Funzionalità di IA"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "Funzionalità IA"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "Dettagli del Marchio"
|
|||
msgid "Brand Website"
|
||||
msgstr "Sito Web del Marchio"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Dettagli aziendali del branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Logo del branding"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Logo del Marchio"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "Preferenze per il branding"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Preferenze di branding aggiornate"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "URL del branding"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "Non riesci a trovare qualcuno?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Determina per quanto tempo i destinatari hanno a disposizione per completare la firma prima che il documento scada. Dopo la scadenza, i destinatari non potranno più firmare il documento."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Controlla le impostazioni email predefinite quando vengono creati nuovi documenti o modelli"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Controlla le impostazioni email predefinite quando vengono creati nuovi documenti o modelli. L’aggiornamento di queste impostazioni non influirà sui documenti o modelli esistenti."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "Campo copiato negli appunti"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "Copia"
|
|||
msgid "Copy Link"
|
||||
msgstr "Copia il link"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Copia ID organizzazione"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Copia il link condivisibile"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "Copia il Link Condivisibile"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Copia link di firma"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Copia ID team"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Copia il token"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "Crea un ticket di supporto"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Crea un team per collaborare con i membri del tuo team."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Crea un modello da questo documento."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "Crea il tuo account e inizia a utilizzare firme digitali all'avanguardia
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "La password corrente è errata."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Destinatari attuali:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Utilizzo corrente rispetto ai limiti dell’organizzazione."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Attualmente tutti i membri dell'organizzazione possono accedere a questo team"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "Data"
|
|||
msgid "Date created"
|
||||
msgstr "Data di creazione"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Formato data"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "Ruolo dell'organizzazione predefinito per nuovi utenti"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Destinatari predefiniti"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Impostazioni predefinite applicate a questa organizzazione."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Impostazioni predefinite applicate a questo team. I valori ereditati provengono dall’organizzazione."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Impostazioni predefinite della firma"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "Valore predefinito"
|
|||
msgid "Default Value"
|
||||
msgstr "Valore predefinito"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Delega proprietà del documento"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Delega della proprietà del documento"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Disabilita l'Autenticazione a Due Fattori prima di eliminare il tuo account."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "Documento Approvato"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Documento Annullato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Documento completato"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "Documento creato da <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Documento creato da modello diretto"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Documento creato da email di modello diretto"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Documento creato usando un <0>link diretto</0>"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "Creazione del documento"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Documento eliminato"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "Il documento è già caricato"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "Il documento utilizza l'inserimento campo legacy"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Lingua del documento"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Limite di documenti superato!"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Documento aperto"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Documento in sospeso"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "Documento rifiutato"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Documento Rifiutato"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Documento rinominato"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Documento inviato"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "Il processo di firma del documento sarà annullato"
|
|||
msgid "Document status"
|
||||
msgstr "Stato del documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Fuso orario del documento"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Titolo del documento"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "Documento visualizzato"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Documento visualizzato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Disegna"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Disegna firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "Rilascia qui il PDF o fai clic per selezionarlo"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "Divulgazione della firma elettronica"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "Email confermato!"
|
|||
msgid "Email Created"
|
||||
msgstr "Email Creata"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "Impostazioni email del documento"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "Dominio email"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "Invia un'email ai destinatari quando vengono rimossi da un documento in
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "Invia un'email ai destinatari con una richiesta di firma"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "Email di risposta (reply-to)"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "Email inviato!"
|
|||
msgid "Email Settings"
|
||||
msgstr "Impostazioni Email"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Invia un’email al proprietario quando un documento viene creato da un modello diretto"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "Invia un'email al proprietario quando un destinatario firma"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "Abilita i token API del team per delegare la proprietà del documento a
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "Inserisci"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Inserisci un nome per la tua nuova cartella. Le cartelle ti aiutano a organizzare i tuoi elementi."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Inserisci un nuovo titolo"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Inserisci nome richiesta"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "Dimensione del carattere del campo"
|
|||
msgid "Field format"
|
||||
msgstr "Formato del campo"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "ID campo:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Autenticazione globale del destinatario"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Impostazioni globali"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "Posta in arrivo"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Documenti in arrivo"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Includi registro di controllo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Includi campi"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Includi destinatari"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Includi dettagli del mittente"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Includi certificato di firma"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Includi i Registri di Audit nel Documento"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "Ereditare dall'organizzazione"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Ereditare i membri dell'organizzazione"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Ereditato"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "Invita i membri del team a collaborare"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Invitali prima all’organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Invitato"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Invitato il"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Unisciti alla nostra comunità su <0>Discord</0> per supporto e discussioni."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Iscritto"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "Iscritto"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Iscritto a {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Identificatori chiave e relazioni per questo team."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Coreano"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "Gestisci account collegati"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Gestisci l'organizzazione"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "Gestisci le sessioni"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Gestisci abbonamento"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Gestisci team"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "Gestisci l'organizzazione {0}"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Gestisci l'abbonamento dell'organizzazione {0}"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Gestisci il team {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Gestisci i gruppi personalizzati di membri per la tua organizzazione."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "Gestisci le impostazioni del tuo sito qui"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "Numero massimo di file caricati consentiti per busta"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "Membro dal"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "Membro dal"
|
|||
msgid "Members"
|
||||
msgstr "Membri"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Membri che attualmente appartengono a questo team."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Messaggio"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "Non trovato"
|
|||
msgid "Not Found"
|
||||
msgstr "Non trovato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "Non impostato"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Non supportato"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "Numero di team consentiti. 0 = Illimitati"
|
|||
msgid "Number Settings"
|
||||
msgstr "Impostazioni Numero"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Disattivato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "Attivato"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "In questa pagina, puoi creare un nuovo webhook."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "Impostazioni del gruppo organizzativo"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "L'organizzazione è stata aggiornata con successo"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "ID organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organizzazione non trovata"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Ruolo dell'organizzazione"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "I modelli di organizzazione sono condivisi tra tutti i team della stessa
|
|||
msgid "Organisation URL"
|
||||
msgstr "URL dell'organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Utilizzo dell’organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Inviti in sospeso a livello di organizzazione per l’organizzazione principale di questo team."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "Sovrascrivi impostazioni organizzazione"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "Sovrascrivi impostazioni organizzazione"
|
|||
msgid "Owner"
|
||||
msgstr "Proprietario"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Documento del proprietario completato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Documento del proprietario creato"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Destinatario del proprietario scaduto"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Proprietà trasferita a {organisationMemberName}."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "Per i documenti in sospeso il processo di firma verrà annullato"
|
|||
msgid "Pending invitations"
|
||||
msgstr "Inviti in sospeso"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Inviti all’organizzazione in sospeso"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "In sospeso dal"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "Email di scadenza per il destinatario"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "Il destinatario non è riuscito a convalidare un token 2FA per il documento"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "ID destinatario:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "Il destinatario ha rifiutato il documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Destinatario rimosso"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "Email destinatario rimosso"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "Email destinatario rimosso"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "Il destinatario ha richiesto un token 2FA per il documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Destinatario ha firmato"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "Email firmato dal destinatario"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "Email firmato dal destinatario"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "Il destinatario ha firmato il documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Richiesta di firma al destinatario"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "Email richiesta firma destinatario"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "Rimuovere l'email del team"
|
|||
msgid "Remove team member"
|
||||
msgstr "Rimuovere il membro del team"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Rinomina"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Rinomina documento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Rinomina template"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "Destra"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Ruolo"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "Righe per pagina"
|
|||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Salva come modello"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "Alcuni firmatari non hanno un campo firma assegnato. Assegna almeno 1 ca
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "Qualcosa è andato storto. Si prega di riprovare più tardi."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Qualcosa è andato storto. Riprova o contatta il supporto."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Si è verificato un errore. Riprova."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Siamo spiacenti, non siamo riusciti a scaricare i log di verifica. Riprova più tardi."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "Compiti del team"
|
|||
msgid "Team Count"
|
||||
msgstr "Numero totale di team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Dettagli del team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "L'email del team è stato rimosso"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "L'email del team è stata revocata per {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Nome email del team"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Email del team rimosso"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "L'email del team è stato aggiornato."
|
|||
msgid "Team Groups"
|
||||
msgstr "Gruppi di team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "ID team"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Gestore del team"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "Gestore del team"
|
|||
msgid "Team Member"
|
||||
msgstr "Membro del team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Membri del team"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "Nome del team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Squadra non trovata"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "Solo team"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "I modelli solo per il team non sono collegati da nessuna parte e sono visibili solo al tuo team."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Ruolo nel team"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "URL del team"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "URL del team"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "URL del team"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "Modello"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Modello (Legacy)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "Il modello utilizza l'inserimento campo legacy"
|
|||
msgid "Template moved"
|
||||
msgstr "Modello spostato"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Template rinominato"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Modello salvato"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "L'email del team <0>{teamEmail}</0> è stata rimossa dal seguente team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "Il team che stai cercando potrebbe essere stato rimosso, rinominato o potrebbe non essere mai esistito."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "Questo documento non può essere duplicato in questo momento. Riprova."
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Questo documento non può essere rinviato in questo momento. Riprova."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "Questo documento non può essere salvato come modello in questo momento. Riprova."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "Questa email conferma che hai rifiutato il documento <0>\"{documentName}
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Questa email è già in uso da un altro team."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "Questa email viene inviata al proprietario del documento quando un destinatario crea un documento tramite un link a un modello diretto."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Questa email viene inviata al proprietario del documento quando un destinatario ha firmato il documento."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "Fuso orario"
|
|||
msgid "Time Zone"
|
||||
msgstr "Fuso orario"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "Digita un indirizzo email per aggiungere un destinatario"
|
|||
msgid "Type your signature"
|
||||
msgstr "Digita la tua firma"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Firma digitata"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Le firme digitate non sono consentite. Si prega di disegnare la propria firma."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "Nome sconosciuto"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Illimitato"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "Carica documenti e aggiungi destinatari"
|
|||
msgid "Upload failed"
|
||||
msgstr "Caricamento fallito"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Carica firma"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Carica Firma"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "User Agent"
|
|||
msgid "User has no password."
|
||||
msgstr "L'utente non ha password."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "ID utente"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Utente non trovato"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "Il tuo documento è stato eliminato da un amministratore!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Il tuo documento è stato reinviato correttamente."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Il tuo documento è stato salvato come modello."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Il tuo documento è stato inviato correttamente."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "Il tuo documento è stato inviato correttamente."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Il tuo documento è stato duplicato correttamente."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Il tuo documento è stato rinominato correttamente."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Il tuo documento è stato aggiornato correttamente"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "Il tuo modello è stato duplicato correttamente."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Il tuo modello è stato eliminato correttamente."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Il tuo template è stato rinominato correttamente."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Il tuo modello è stato aggiornato correttamente"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: ja\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 プロフィールが見つかりません"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 チームが見つかりません"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "組織を一意に識別する URL"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "チームを識別するための一意の URL"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "有効なメールアドレスを入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "入力されたメールアドレス宛てに確認メールが送信されます。"
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "メールの末尾に表示する追加のブランド情報"
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "文書に電子的に署名すると、記録用にその文書を表示
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "送信後、自動的にドキュメントが生成され、「ドキュメント」ページに追加されます。メールでも通知が届きます。"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "AI 機能"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "AI 機能"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "ブランド詳細"
|
|||
msgid "Brand Website"
|
||||
msgstr "ブランドの Web サイト"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "ブランディング"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "ブランディング用の会社情報"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "ブランディング用ロゴ"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "ブランディングロゴ"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "ブランディング設定"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "ブランディング設定を更新しました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "ブランディング用 URL"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "メンバーが見つかりませんか?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "受信者が文書の有効期限切れまでに署名を完了できる期間を設定します。有効期限後は、受信者は文書に署名できなくなります。"
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "新しいドキュメントやテンプレートを作成する際の既定のメール設定を制御します"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "新しいドキュメントまたはテンプレートを作成する際のデフォルトのメール設定を管理します。これらの設定を更新しても、既存のドキュメントやテンプレートには影響しません。"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "フィールドをクリップボードにコピーしました"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "コピー"
|
|||
msgid "Copy Link"
|
||||
msgstr "リンクをコピー"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "組織 ID をコピー"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "共有リンクをコピー"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "共有リンクをコピー"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "署名リンクをコピー"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "チーム ID をコピー"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "トークンをコピー"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "サポートチケットを作成"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "チームメンバーと共同作業するためのチームを作成します。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "このドキュメントからテンプレートを作成します。"
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "アカウントを作成して、最先端の文書署名を今すぐ始
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "現在のパスワードが正しくありません。"
|
|||
msgid "Current recipients:"
|
||||
msgstr "現在の受信者:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "組織の上限に対する現在の利用状況。"
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "現在、すべての組織メンバーがこのチームにアクセスできます"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "日付"
|
|||
msgid "Date created"
|
||||
msgstr "作成日"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "日付形式"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "新規ユーザーの既定の組織ロール"
|
|||
msgid "Default Recipients"
|
||||
msgstr "デフォルトの受信者"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "この組織に適用されているデフォルト設定です。"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "このチームに適用されているデフォルト設定です。継承された値は組織から引き継がれます。"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "既定の署名設定"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "デフォルト値"
|
|||
msgid "Default Value"
|
||||
msgstr "既定値"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "ドキュメント所有権の委任"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "文書の所有権を委譲する"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "アカウントを削除する前に二要素認証を無効にしてください。"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "文書が承認されました"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "文書はキャンセルされました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "文書が完了しました"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "文書は <0>{0}</0> によって作成されました"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "ダイレクトテンプレートから作成されたドキュメント"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "ダイレクトテンプレートメールから作成されたドキュメント"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "<0>ダイレクトリンク</0>から文書が作成されました"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "ドキュメント作成"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "文書を削除しました"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "ドキュメントはすでにアップロードされています"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "ドキュメントは旧式のフィールド挿入を使用しています"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "ドキュメントの言語"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "文書数の上限を超えました"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "ドキュメントが開かれました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "文書は保留中です"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "ドキュメントは却下されました"
|
|||
msgid "Document Rejected"
|
||||
msgstr "ドキュメントを却下しました"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "ドキュメント名を変更しました"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "文書を送信しました"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "文書の署名プロセスはキャンセルされます"
|
|||
msgid "Document status"
|
||||
msgstr "文書のステータス"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "ドキュメントのタイムゾーン"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "文書タイトル"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "ドキュメントが閲覧されました"
|
|||
msgid "Document Viewed"
|
||||
msgstr "文書が閲覧されました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "手書き"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "手書き署名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "PDFファイルをここにドロップするか、クリックして選択してください"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "電子署名に関する開示"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "メールアドレスが確認されました!"
|
|||
msgid "Email Created"
|
||||
msgstr "メールが作成されました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "ドキュメントのメール設定"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "メールドメイン"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "自分が保留中のドキュメントから削除されたときに受
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "署名の依頼を受信者へメール送信する"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "メールの reply-to"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "メールを送信しました!"
|
|||
msgid "Email Settings"
|
||||
msgstr "メール設定"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "ダイレクトテンプレートからドキュメントが作成されたときに、所有者にメールで通知する"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "受信者が署名したときに所有者へメール通知する"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "チーム API トークンを有効にして、別のチームメンバ
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "入力してください"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "新しいフォルダ名を入力してください。フォルダを使うとアイテムを整理できます。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "新しいタイトルを入力してください"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "クレーム名を入力"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "フィールドのフォントサイズ"
|
|||
msgid "Field format"
|
||||
msgstr "フィールド形式"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "フィールドID:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "グローバル受信者アクション認証"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "グローバル設定"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "受信箱"
|
|||
msgid "Inbox documents"
|
||||
msgstr "受信箱の文書"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "監査ログを含める"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "フィールドを含める"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "受信者を含める"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "送信者情報を含める"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "署名証明書を含める"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "監査ログをドキュメントに含める"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "組織から継承"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "組織メンバーを継承"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "継承"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "チームメンバーを招待してコラボレーション"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "まずは組織に招待してください"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "招待済み"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "招待日時"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "コミュニティサポートやディスカッションのために、<0>Discord</0> のコミュニティに参加してください。"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "参加日"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "参加日"
|
|||
msgid "Joined {0}"
|
||||
msgstr "{0} に参加"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "このチームの主要な識別子と関連付けです。"
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "韓国語"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "リンク済みアカウントを管理"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "組織を管理"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "セッション管理"
|
|||
msgid "Manage subscription"
|
||||
msgstr "サブスクリプションを管理"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "チームを管理"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "{0} 組織を管理"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "{0} 組織のサブスクリプションを管理"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "{0} チームを管理"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "組織メンバーのカスタムグループを管理します。"
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "ここでサイト設定を管理できます"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "封筒ごとにアップロードできる最大ファイル数"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "メンバー登録日"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "メンバー登録日"
|
|||
msgid "Members"
|
||||
msgstr "メンバー"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "現在このチームに所属しているメンバー。"
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "メッセージ"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "見つかりません"
|
|||
msgid "Not Found"
|
||||
msgstr "見つかりません"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "未設定"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "サポートされていません"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "許可されるチーム数。0 = 無制限"
|
|||
msgid "Number Settings"
|
||||
msgstr "数値の設定"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "オフ"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "オン"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "このページでは新しい Webhook を作成できます。"
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "組織グループ設定"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "組織は正常に更新されました"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "組織 ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "組織が見つかりません"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "組織ロール"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "組織テンプレートは、同じ組織内のすべてのチームで
|
|||
msgid "Organisation URL"
|
||||
msgstr "組織 URL"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "組織の使用状況"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "このチームの親組織に対する、組織レベルの保留中の招待。"
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "組織設定を上書き"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "組織設定を上書き"
|
|||
msgid "Owner"
|
||||
msgstr "所有者"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "所有者向けドキュメント完了"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "所有者向けドキュメント作成"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "所有者向け受信者の有効期限切れ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "所有権を {organisationMemberName} に移転しました。"
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "保留中のドキュメントは署名プロセスがキャンセルさ
|
|||
msgid "Pending invitations"
|
||||
msgstr "保留中の招待"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "保留中の組織招待"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "保留開始日時"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "受信者の期限切れメール"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "受信者は文書用の2要素認証トークンを検証できませんでした"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "受信者ID:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "受信者が文書を却下しました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "受信者が削除されました"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "受信者削除メール"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "受信者削除メール"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "受信者が文書用の2要素認証トークンをリクエストしました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "受信者が署名しました"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "受信者署名メール"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "受信者署名メール"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "受信者が文書に署名しました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "受信者への署名リクエスト"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "受信者署名依頼メール"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "チームのメールアドレスを削除"
|
|||
msgid "Remove team member"
|
||||
msgstr "チームメンバーを削除"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "名前を変更"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "ドキュメント名を変更"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "テンプレート名を変更"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "右"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "役割"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "ページあたりの行数"
|
|||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "テンプレートとして保存"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "一部の署名者に署名フィールドが割り当てられていま
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "問題が発生しました。後でもう一度お試しください。
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "問題が発生しました。もう一度お試しいただくか、サポートまでお問い合わせください。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "問題が発生しました。もう一度お試しください。"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "監査ログをダウンロードできませんでした。後でもう一度お試しください。"
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "チーム割り当て"
|
|||
msgid "Team Count"
|
||||
msgstr "チーム数"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "チームの詳細"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "チームのメールアドレスを削除しました"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "{0} のチームメールが取り消されました"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "チームのメール名"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "チームメールが削除されました"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "チームのメールアドレスを更新しました。"
|
|||
msgid "Team Groups"
|
||||
msgstr "チームグループ"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "チーム ID"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "チームマネージャー"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "チームマネージャー"
|
|||
msgid "Team Member"
|
||||
msgstr "チームメンバー"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "チームメンバー"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "チーム名"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "チームが見つかりません"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "チーム専用"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "チーム専用テンプレートはどこにもリンクされず、あなたのチームだけが閲覧できます。"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "チームロール"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "チーム URL"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "チーム URL"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "チーム URL"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "テンプレート"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "テンプレート(レガシー)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "テンプレートは旧式のフィールド挿入を使用していま
|
|||
msgid "Template moved"
|
||||
msgstr "テンプレートを移動しました"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "テンプレート名を変更しました"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "テンプレートを保存しました"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "チームメール <0>{teamEmail}</0> は、次のチームから削除されました"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "お探しのチームは削除されたか、名前が変更されたか、もともと存在しなかった可能性があります。"
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "この文書は現在複製できません。もう一度お試しくだ
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "この文書は現在再送信できません。もう一度お試しください。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "現在、このドキュメントをテンプレートとして保存できません。もう一度お試しください。"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "このメールは、{documentOwnerName} から送信されたドキュ
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "このメールアドレスは別のチームですでに使用されています。"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "このメールは、受信者がダイレクトテンプレートリンクを介してドキュメントを作成したときに、ドキュメントの所有者に送信されます。"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "このメールは、受信者がドキュメントに署名したときにドキュメント所有者に送信されます。"
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "タイムゾーン"
|
|||
msgid "Time Zone"
|
||||
msgstr "タイムゾーン"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "受信者を追加するメールアドレスを入力してください
|
|||
msgid "Type your signature"
|
||||
msgstr "署名を入力してください"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "タイプ入力の署名"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "タイプ入力された署名は使用できません。署名を描画してください。"
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "不明な名前"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "無制限"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "文書をアップロードして受信者を追加"
|
|||
msgid "Upload failed"
|
||||
msgstr "アップロードに失敗しました"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "署名をアップロード"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "署名をアップロード"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "ユーザーエージェント"
|
|||
msgid "User has no password."
|
||||
msgstr "このユーザーにはパスワードが設定されていません。"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "ユーザー ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "ユーザーが見つかりません"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "管理者によってドキュメントが削除されました。"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "文書を正常に再送信しました。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "ドキュメントはテンプレートとして保存されました。"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "文書を正常に送信しました。"
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "文書を正常に送信しました。"
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "文書を正常に複製しました。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "ドキュメント名は正常に変更されました。"
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "ドキュメントは正常に更新されました"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "テンプレートを正常に複製しました。"
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "テンプレートは正常に削除されました。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "テンプレート名は正常に変更されました。"
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "テンプレートは正常に更新されました"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: ko\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Korean\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 프로필을 찾을 수 없습니다"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 팀을 찾을 수 없습니다"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "조직을 식별하기 위한 고유 URL"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "팀을 식별하기 위한 고유 URL"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "유효한 이메일 주소를 입력해야 합니다"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "입력한 이메일 주소로 확인 이메일이 전송됩니다."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "이메일 하단에 표시할 추가 브랜드 정보"
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "전자 서명을 완료한 후에는, 기록용으로 문서를 열람
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "제출이 완료되면 문서가 자동으로 생성되어 문서 페이지에 추가됩니다. 또한 이메일로 알림을 받게 됩니다."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "AI 기능들"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "AI 기능"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "브랜드 세부 정보"
|
|||
msgid "Brand Website"
|
||||
msgstr "브랜드 웹사이트"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "브랜딩"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "브랜딩 회사 정보"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "브랜딩 로고"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "브랜딩 로고"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "브랜딩 환경설정"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "브랜딩 환경설정이 업데이트되었습니다"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "브랜딩 URL"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "누군가를 찾을 수 없나요?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "수신자가 문서가 만료되기 전에 서명을 완료할 수 있는 기간을 제어합니다. 만료 후에는 수신자가 더 이상 이 문서에 서명할 수 없습니다."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "새 문서 또는 템플릿을 생성할 때 사용할 기본 이메일 설정을 제어합니다."
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "새 문서나 템플릿을 만들 때 기본 이메일 설정을 제어합니다. 이 설정을 업데이트해도 기존 문서나 템플릿에는 영향을 주지 않습니다."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "필드를 클립보드에 복사했습니다."
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "복사"
|
|||
msgid "Copy Link"
|
||||
msgstr "링크 복사"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "조직 ID 복사"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "공유 가능한 링크 복사"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "공유 가능한 링크 복사"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "서명 링크 복사"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "팀 ID 복사"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "토큰 복사"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "지원 티켓 생성"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "팀원과 협업할 수 있는 팀을 생성하세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "이 문서에서 템플릿을 생성합니다."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "계정을 만들고 최첨단 전자 서명 서비스를 시작하세요
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "현재 비밀번호가 올바르지 않습니다."
|
|||
msgid "Current recipients:"
|
||||
msgstr "현재 수신자:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "조직 한도 대비 현재 사용량입니다."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "현재 모든 조직 구성원이 이 팀에 접근할 수 있습니다."
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "날짜"
|
|||
msgid "Date created"
|
||||
msgstr "생성 날짜"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "날짜 형식"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "새 사용자 기본 조직 역할"
|
|||
msgid "Default Recipients"
|
||||
msgstr "기본 수신인들"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "이 조직에 기본 설정이 적용되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "이 팀에 기본 설정이 적용되었습니다. 상속된 값은 조직에서 가져옵니다."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "기본 서명 설정"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "기본 값"
|
|||
msgid "Default Value"
|
||||
msgstr "기본값"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "문서 소유권 위임"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "문서 소유권 위임"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "계정을 삭제하기 전에 2단계 인증을 비활성화해야 합니다."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "문서 승인됨"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "문서가 취소됨"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "문서 완료됨"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "문서가 <0>{0}</0>에 의해 생성되었습니다"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "직접 템플릿에서 생성된 문서"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "직접 템플릿 이메일에서 생성된 문서"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "문서가 <0>직접 링크</0>를 사용해 생성되었습니다"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "문서 생성"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "문서가 삭제되었습니다"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "문서가 이미 업로드되었습니다."
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "문서가 기존(레거시) 필드 삽입 방식을 사용하고 있습니다."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "문서 언어"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "문서 한도 초과!"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "문서가 열렸습니다."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "문서 보류 중"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "문서 거부됨"
|
|||
msgid "Document Rejected"
|
||||
msgstr "문서가 거부되었습니다"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "문서 이름이 변경되었습니다."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "문서가 발송되었습니다"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "문서 서명 프로세스가 취소됩니다"
|
|||
msgid "Document status"
|
||||
msgstr "문서 상태"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "문서 시간대"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "문서 제목"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "문서가 열람되었습니다."
|
|||
msgid "Document Viewed"
|
||||
msgstr "문서 열람 완료"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "그리기"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "서명 그리기"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "여기에 PDF를 끌어다 놓거나 클릭하여 선택하세요"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "전자 서명 고지"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "이메일이 확인되었습니다!"
|
|||
msgid "Email Created"
|
||||
msgstr "이메일이 생성되었습니다"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "이메일 문서 설정"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "이메일 도메인"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "보류 중인 문서에서 수신자가 제거되면 이메일 보내기
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "서명을 요청하는 이메일을 수신자에게 보내기"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "이메일 회신 주소"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "이메일이 전송되었습니다!"
|
|||
msgid "Email Settings"
|
||||
msgstr "이메일 설정"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "직접 템플릿에서 문서가 생성되면 소유자에게 이메일 보내기"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "수신자가 서명하면 소유자에게 이메일 보내기"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "팀 API 토큰을 활성화하여 문서 소유권을 다른 팀 구성
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "입력하세요"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "새 폴더 이름을 입력하세요. 폴더는 항목을 정리하는 데 도움이 됩니다."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "새 제목을 입력하세요."
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "클레임 이름 입력"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "필드 글꼴 크기"
|
|||
msgid "Field format"
|
||||
msgstr "필드 형식"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "필드 ID:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "전역 수신자 액션 인증"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "전역 설정"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "받은편지함"
|
|||
msgid "Inbox documents"
|
||||
msgstr "받은편지함 문서"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "감사 로그 포함"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "필드 포함"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "수신자 포함"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "발신자 정보 포함"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "서명 인증서 포함"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "문서에 감사 로그 포함"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "조직에서 상속"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "조직 구성원 상속"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "상속됨"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "팀 구성원을 초대하여 협업하세요."
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "먼저 해당 사용자를 조직에 초대하세요."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "초대됨"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "초대 일시"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "커뮤니티 지원과 논의를 위해 <0>Discord</0> 커뮤니티에 참여하세요."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "가입일"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "가입일"
|
|||
msgid "Joined {0}"
|
||||
msgstr "{0}에 가입함"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "이 팀에 대한 주요 식별자와 관계입니다."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "한국어"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "연결된 계정 관리"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "조직 관리"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "세션 관리"
|
|||
msgid "Manage subscription"
|
||||
msgstr "구독 관리"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "팀 관리"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "{0} 조직 관리"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "{0} 조직 구독 관리"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "{0} 팀 관리"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "조직의 사용자 정의 그룹을 관리합니다."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "사이트 설정을 여기에서 관리할 수 있습니다"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "봉투당 허용되는 최대 업로드 파일 수"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "가입일"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "가입일"
|
|||
msgid "Members"
|
||||
msgstr "구성원"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "현재 이 팀에 속해 있는 구성원입니다."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "메시지"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "찾을 수 없음"
|
|||
msgid "Not Found"
|
||||
msgstr "찾을 수 없음"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "설정되지 않음"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "지원되지 않습니다"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "허용되는 팀 수. 0 = 무제한"
|
|||
msgid "Number Settings"
|
||||
msgstr "숫자 설정"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "꺼짐"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "켜짐"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "이 페이지에서 새 웹훅을 생성할 수 있습니다."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "조직 그룹 설정"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "조직이 성공적으로 업데이트되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "조직 ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "조직을 찾을 수 없습니다."
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "조직 역할"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "조직 템플릿은 동일한 조직 내의 모든 팀에서 공유됩
|
|||
msgid "Organisation URL"
|
||||
msgstr "조직 URL"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "조직 사용량"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "이 팀이 속한 상위 조직에 대한 조직 수준 보류 중 초대입니다."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "조직 설정 재정의"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "조직 설정 재정의"
|
|||
msgid "Owner"
|
||||
msgstr "소유자"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "소유자 문서 완료"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "소유자 문서 생성"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "소유자 수신자 만료"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "소유권이 {organisationMemberName}에게 이전되었습니다."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "보류 중인 문서는 서명 절차가 취소됩니다"
|
|||
msgid "Pending invitations"
|
||||
msgstr "보류 중인 초대장"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "보류 중인 조직 초대"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "다음 시점부터 보류 중"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "수신자 만료 이메일"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "수신자가 문서에 대한 2FA 토큰 검증에 실패했습니다"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "수신자 ID:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "수신자가 문서를 거부했습니다"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "수신자 제거됨"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "수신자 제거 이메일"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "수신자 제거 이메일"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "수신자가 문서에 대한 2FA 토큰을 요청했습니다"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "수신자 서명 완료"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "수신자 서명 완료 이메일"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "수신자 서명 완료 이메일"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "수신자가 문서에 서명했습니다"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "수신자 서명 요청"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "수신자 서명 요청 이메일"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "팀 이메일 제거"
|
|||
msgid "Remove team member"
|
||||
msgstr "팀 구성원 제거"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "이름 변경"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "문서 이름 변경"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "템플릿 이름 변경"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "오른쪽"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "역할"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "페이지당 행 수"
|
|||
msgid "Save"
|
||||
msgstr "저장"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "템플릿으로 저장"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "일부 서명자에게 서명 필드가 할당되지 않았습니다.
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "문제가 발생했습니다. 잠시 후 다시 시도해 주세요."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "문제가 발생했습니다. 다시 시도하시거나 지원팀에 문의해 주세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "문제가 발생했습니다. 다시 시도해주세요."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "감사 로그를 다운로드할 수 없습니다. 나중에 다시 시도해 주세요."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "팀 할당"
|
|||
msgid "Team Count"
|
||||
msgstr "팀 수"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "팀 세부정보"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "팀 이메일이 제거되었습니다"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "{0}에 대한 팀 이메일이 해지되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "팀 이메일 이름"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "팀 이메일 제거됨"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "팀 이메일이 업데이트되었습니다."
|
|||
msgid "Team Groups"
|
||||
msgstr "팀 그룹"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "팀 ID"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "팀 매니저"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "팀 매니저"
|
|||
msgid "Team Member"
|
||||
msgstr "팀 구성원"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "팀 구성원"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "팀 이름"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "팀을 찾을 수 없습니다."
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "팀 전용"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "팀 전용 템플릿은 어디에도 연결되지 않으며, 팀원만 볼 수 있습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "팀 역할"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "팀 URL"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "팀 URL"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "팀 URL"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "템플릿"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "템플릿(레거시)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "템플릿이 기존(레거시) 필드 삽입 방식을 사용하고 있
|
|||
msgid "Template moved"
|
||||
msgstr "템플릿이 이동되었습니다"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "템플릿 이름이 변경되었습니다."
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "템플릿이 저장되었습니다"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "팀 이메일 <0>{teamEmail}</0>이 다음 팀에서 제거되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "찾고 있는 팀은 삭제되었거나 이름이 변경되었거나 처음부터 존재하지 않았을 수 있습니다."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "현재 이 문서를 복제할 수 없습니다. 다시 시도해 주세
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "현재 이 문서를 재전송할 수 없습니다. 다시 시도해 주세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "현재 이 문서를 템플릿으로 저장할 수 없습니다. 다시 시도해 주세요."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "이 이메일은 {documentOwnerName}님이 보낸 <0>\"{documentName}\"<
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "이 이메일은 이미 다른 팀에서 사용 중입니다."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "이 이메일은 수신자가 직접 템플릿 링크를 통해 문서를 생성했을 때 문서 소유자에게 전송됩니다."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "이 이메일은 수신자가 문서에 서명했을 때 문서 소유자에게 전송됩니다."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "시간대"
|
|||
msgid "Time Zone"
|
||||
msgstr "시간대"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "수신자를 추가하려면 이메일 주소를 입력하세요."
|
|||
msgid "Type your signature"
|
||||
msgstr "서명 내용을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "입력한 서명"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "입력식 서명은 허용되지 않습니다. 서명을 직접 그려 주세요."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "이름을 알 수 없음"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "무제한"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "문서를 업로드하고 수신자를 추가하세요"
|
|||
msgid "Upload failed"
|
||||
msgstr "업로드 실패"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "서명 업로드"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "서명 업로드"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "User Agent"
|
|||
msgid "User has no password."
|
||||
msgstr "사용자에게 설정된 비밀번호가 없습니다."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "사용자 ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "사용자를 찾을 수 없습니다."
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "관리자가 귀하의 문서를 삭제했습니다!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "문서가 성공적으로 재전송되었습니다."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "문서가 템플릿으로 저장되었습니다."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "문서가 성공적으로 발송되었습니다."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "문서가 성공적으로 발송되었습니다."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "문서가 성공적으로 복제되었습니다."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "문서 이름이 성공적으로 변경되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "문서가 성공적으로 업데이트되었습니다."
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "템플릿이 성공적으로 복제되었습니다."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "템플릿이 성공적으로 삭제되었습니다."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "템플릿 이름이 성공적으로 변경되었습니다."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "템플릿이 성공적으로 업데이트되었습니다."
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Language: nl\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 04:58\n"
|
||||
"PO-Revision-Date: 2026-04-02 08:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
|
@ -852,6 +852,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Profiel niet gevonden"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Team niet gevonden"
|
||||
|
|
@ -1015,6 +1017,10 @@ msgstr "Een unieke URL om je organisatie te identificeren"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Een unieke URL om je team te identificeren"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr "Een geldig e-mailadres is vereist"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Er wordt een verificatie-e-mail naar het opgegeven e-mailadres verzonden."
|
||||
|
|
@ -1391,6 +1397,7 @@ msgstr "Aanvullende merkinformatie om onderaan e‑mails weer te geven"
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1439,6 +1446,10 @@ msgstr "Na het elektronisch ondertekenen van een document krijg je de mogelijkhe
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Na indiening wordt er automatisch een document gegenereerd en toegevoegd aan je documentenpagina. Je ontvangt ook een melding per e-mail."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr "AI-functies"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "AI-functies"
|
||||
|
|
@ -2209,12 +2220,21 @@ msgstr "Merkdetails"
|
|||
msgid "Brand Website"
|
||||
msgstr "Website van merk"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr "Bedrijfsgegevens voor branding"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr "Branding-logo"
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Branding-logo"
|
||||
|
|
@ -2233,6 +2253,10 @@ msgstr "Brandingvoorkeuren"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Brandingvoorkeuren bijgewerkt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr "Branding-URL"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2330,6 +2354,8 @@ msgstr "Kunt u niemand vinden?"
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2881,8 +2907,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr "Bepaalt hoe lang ontvangers de tijd hebben om te ondertekenen voordat het document verloopt. Na de vervaldatum kunnen ontvangers het document niet meer ondertekenen."
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Bepaalt de standaard e-mailinstellingen wanneer nieuwe documenten of sjablonen worden aangemaakt"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr "Bepaalt de standaard e-mailinstellingen wanneer nieuwe documenten of sjablonen worden aangemaakt. Het bijwerken van deze instellingen heeft geen invloed op bestaande documenten of sjablonen."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2944,6 +2970,7 @@ msgstr "Veld naar klembord gekopieerd"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2960,6 +2987,10 @@ msgstr "Kopiëren"
|
|||
msgid "Copy Link"
|
||||
msgstr "Link kopiëren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr "Organisatie-ID kopiëren"
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Deelbare link kopiëren"
|
||||
|
|
@ -2973,6 +3004,10 @@ msgstr "Deelbare link kopiëren"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Ondertekeningslinks kopiëren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr "Team-ID kopiëren"
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Token kopiëren"
|
||||
|
|
@ -3015,6 +3050,10 @@ msgstr "Maak een supportticket aan"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Maak een team aan om samen te werken met je teamleden."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr "Maak een sjabloon van dit document."
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3192,6 +3231,8 @@ msgstr "Maak je account aan en begin met het gebruik van moderne documentenonder
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3247,6 +3288,10 @@ msgstr "Het huidige wachtwoord is onjuist."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Huidige ontvangers:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr "Huidig gebruik ten opzichte van organisatielimieten."
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Momenteel hebben alle organisatieleden toegang tot dit team"
|
||||
|
|
@ -3296,6 +3341,10 @@ msgstr "Datum"
|
|||
msgid "Date created"
|
||||
msgstr "Aanmaakdatum"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr "Datumnotatie"
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3353,6 +3402,14 @@ msgstr "Standaard organisatierol voor nieuwe gebruikers"
|
|||
msgid "Default Recipients"
|
||||
msgstr "Standaardontvangers"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr "Standaardinstellingen toegepast op deze organisatie."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr "Standaardinstellingen toegepast op dit team. Overgenomen waarden komen van de organisatie."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Standaardinstellingen voor handtekeningen"
|
||||
|
|
@ -3372,6 +3429,10 @@ msgstr "Standaardwaarde"
|
|||
msgid "Default Value"
|
||||
msgstr "Standaardwaarde"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr "Documenteigendom delegeren"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr "Documenteigendom delegeren"
|
||||
|
|
@ -3707,6 +3768,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Schakel twee‑factor‑authenticatie uit voordat je je account verwijdert."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3826,6 +3888,7 @@ msgstr "Document goedgekeurd"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Document geannuleerd"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Document voltooid"
|
||||
|
|
@ -3870,6 +3933,10 @@ msgstr "Document aangemaakt door <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Document aangemaakt via directe sjabloon"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr "Document gemaakt vanuit directe sjabloon-e-mail"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Document aangemaakt via een <0>directe link</0>"
|
||||
|
|
@ -3881,6 +3948,7 @@ msgstr "Documentcreatie"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Document verwijderd"
|
||||
|
|
@ -3947,6 +4015,10 @@ msgstr "Document is al geüpload"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "Document gebruikt verouderde veldinvoeging"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr "Documenttaal"
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Documentlimiet overschreden!"
|
||||
|
|
@ -3973,6 +4045,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Document geopend"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Document in behandeling"
|
||||
|
|
@ -4009,6 +4082,10 @@ msgstr "Document geweigerd"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Document geweigerd"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr "Document hernoemd"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Document verzonden"
|
||||
|
|
@ -4041,6 +4118,10 @@ msgstr "Het ondertekeningsproces van het document wordt geannuleerd"
|
|||
msgid "Document status"
|
||||
msgstr "Documentstatus"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr "Documenttijdzone"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Documenttitel"
|
||||
|
|
@ -4090,6 +4171,7 @@ msgstr "Document bekeken"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Document bekeken"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4279,6 +4361,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Tekenen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr "Handtekening tekenen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr "Zet de pdf hier neer of klik om te selecteren"
|
||||
|
|
@ -4427,7 +4513,7 @@ msgstr "Kennisgeving elektronische handtekening"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4476,6 +4562,10 @@ msgstr "E‑mail bevestigd!"
|
|||
msgid "Email Created"
|
||||
msgstr "E-mail aangemaakt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr "Instellingen voor document-e-mail"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr "E-maildomein"
|
||||
|
|
@ -4537,6 +4627,10 @@ msgstr "E-mail ontvangers wanneer ze uit een in behandeling zijnd document worde
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr "E-mail ontvangers met een ondertekeningsverzoek"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr "E-mail reply-to"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4562,6 +4656,10 @@ msgstr "E‑mail verzonden!"
|
|||
msgid "Email Settings"
|
||||
msgstr "E-mailinstellingen"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr "Stuur een e-mail naar de eigenaar wanneer een document wordt aangemaakt vanuit een directe sjabloon"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr "E-mail de eigenaar wanneer een ontvanger ondertekent"
|
||||
|
|
@ -4679,6 +4777,7 @@ msgstr "Schakel team-API-tokens in om documenteigendom aan een ander teamlid te
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4717,6 +4816,10 @@ msgstr "Invoeren"
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Voer een naam in voor je nieuwe map. Mappen helpen je je items te organiseren."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr "Voer een nieuwe titel in"
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Voer claimnaam in"
|
||||
|
|
@ -5174,6 +5277,11 @@ msgstr "Lettergrootte veld"
|
|||
msgid "Field format"
|
||||
msgstr "Veldopmaak"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr "Veld-ID:"
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5371,6 +5479,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Globale ontvangeractie-authenticatie"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr "Algemene instellingen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5697,6 +5812,26 @@ msgstr "Inbox"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Inboxdocumenten"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr "Auditlog bijvoegen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr "Velden opnemen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr "Ontvangers opnemen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr "Afzendergegevens bijvoegen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr "Ondertekeningscertificaat bijvoegen"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Auditlogs opnemen in het document"
|
||||
|
|
@ -5740,6 +5875,10 @@ msgstr "Overnemen van organisatie"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Organisatieleden overnemen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr "Overgenomen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5865,6 +6004,10 @@ msgstr "Teamleden uitnodigen om samen te werken"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr "Nodig ze eerst uit voor de organisatie"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr "Uitgenodigd"
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Uitgenodigd op"
|
||||
|
|
@ -5934,6 +6077,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Word lid van onze community op <0>Discord</0> voor ondersteuning en discussie."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Lid geworden"
|
||||
|
||||
|
|
@ -5942,6 +6087,10 @@ msgstr "Lid geworden"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Toegetreden {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr "Belangrijke identificatoren en relaties voor dit team."
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr "Koreaans"
|
||||
|
|
@ -6252,6 +6401,7 @@ msgstr "Gekoppelde accounts beheren"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Organisatie beheren"
|
||||
|
||||
|
|
@ -6281,6 +6431,10 @@ msgstr "Sessies beheren"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Abonnement beheren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr "Team beheren"
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6291,6 +6445,11 @@ msgstr "De organisatie {0} beheren"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Het abonnement voor de organisatie {0} beheren"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr "Het team {0} beheren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Beheer de aangepaste groepen leden voor je organisatie."
|
||||
|
|
@ -6341,6 +6500,7 @@ msgstr "Beheer hier je site‑instellingen"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6396,6 +6556,8 @@ msgstr "Maximaal toegestaan aantal geüploade bestanden per envelop"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6417,6 +6579,8 @@ msgstr "Lid sinds"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6424,6 +6588,10 @@ msgstr "Lid sinds"
|
|||
msgid "Members"
|
||||
msgstr "Leden"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr "Leden die momenteel tot dit team behoren."
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Bericht"
|
||||
|
|
@ -6854,6 +7022,10 @@ msgstr "Niet gevonden"
|
|||
msgid "Not Found"
|
||||
msgstr "Niet gevonden"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr "Niet ingesteld"
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Niet ondersteund"
|
||||
|
|
@ -6896,6 +7068,14 @@ msgstr "Aantal toegestane teams. 0 = onbeperkt"
|
|||
msgid "Number Settings"
|
||||
msgstr "Nummer-instellingen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr "Uit"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr "Aan"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "Op deze pagina kun je een nieuwe webhook aanmaken."
|
||||
|
|
@ -7034,6 +7214,10 @@ msgstr "Instellingen organisatiegroep"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "Organisatie is succesvol bijgewerkt"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr "Organisatie-ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7076,6 +7260,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organisatie niet gevonden"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Organisatierol"
|
||||
|
||||
|
|
@ -7115,6 +7300,14 @@ msgstr "Organisatiesjablonen worden gedeeld tussen alle teams binnen dezelfde or
|
|||
msgid "Organisation URL"
|
||||
msgstr "Organisatie-URL"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr "Organisatiegebruik"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr "Openstaande uitnodigingen op organisatieniveau voor de moederorganisatie van dit team."
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7166,6 +7359,7 @@ msgstr "Organisatie-instellingen overschrijven"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7174,6 +7368,18 @@ msgstr "Organisatie-instellingen overschrijven"
|
|||
msgid "Owner"
|
||||
msgstr "Eigenaar"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr "Document van eigenaar voltooid"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr "Document van eigenaar aangemaakt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr "Ontvanger van eigenaar verlopen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Eigendom overgedragen aan {organisationMemberName}."
|
||||
|
|
@ -7325,6 +7531,10 @@ msgstr "Bij in behandeling zijnde documenten wordt het ondertekeningsproces gean
|
|||
msgid "Pending invitations"
|
||||
msgstr "Openstaande uitnodigingen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr "Openstaande organisatie-uitnodigingen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr "In behandeling sinds"
|
||||
|
|
@ -7893,10 +8103,19 @@ msgstr "E-mail over verlopen ondertekenaar"
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr "Ontvanger kon een 2FA-token voor het document niet valideren"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr "Ontvanger-ID:"
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr "Ontvanger heeft het document afgewezen"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr "Ontvanger verwijderd"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "E-mail bij verwijderde ontvanger"
|
||||
|
|
@ -7905,6 +8124,10 @@ msgstr "E-mail bij verwijderde ontvanger"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr "Ontvanger heeft een 2FA-token voor het document aangevraagd"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr "Ontvanger heeft ondertekend"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "E-mail bij ondertekende ontvanger"
|
||||
|
|
@ -7913,6 +8136,10 @@ msgstr "E-mail bij ondertekende ontvanger"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr "Ontvanger heeft het document ondertekend"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr "Ondertekeningsverzoek voor ontvanger"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "E-mail voor ondertekeningsverzoek aan ontvanger"
|
||||
|
|
@ -8115,6 +8342,21 @@ msgstr "Team‑e‑mail verwijderen"
|
|||
msgid "Remove team member"
|
||||
msgstr "Teamlid verwijderen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr "Hernoemen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr "Document hernoemen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr "Template hernoemen"
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8365,6 +8607,8 @@ msgstr "Rechts"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Rol"
|
||||
|
||||
|
|
@ -8386,6 +8630,15 @@ msgstr "Rijen per pagina"
|
|||
msgid "Save"
|
||||
msgstr "Opslaan"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr "Opslaan als sjabloon"
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9160,6 +9413,7 @@ msgstr "Sommige ondertekenaars hebben geen handtekeningveld toegewezen gekregen.
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9273,6 +9527,10 @@ msgstr "Er is iets misgegaan. Probeer het later opnieuw."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Er is iets misgegaan. Probeer het opnieuw of neem contact op met support."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr "Er is iets misgegaan. Probeer het opnieuw."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "We konden de auditlogs niet downloaden. Probeer het later opnieuw."
|
||||
|
|
@ -9557,6 +9815,11 @@ msgstr "Teamtoewijzingen"
|
|||
msgid "Team Count"
|
||||
msgstr "Aantal teams"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr "Teamdetails"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9579,6 +9842,10 @@ msgstr "Team‑e‑mail is verwijderd"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "Teame-mailadres is ingetrokken voor {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr "Team-e-mailnaam"
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "Teame-mailadres verwijderd"
|
||||
|
|
@ -9603,6 +9870,11 @@ msgstr "Team‑e‑mail is bijgewerkt."
|
|||
msgid "Team Groups"
|
||||
msgstr "Teamgroepen"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr "Team-ID"
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Teammanager"
|
||||
|
|
@ -9612,6 +9884,7 @@ msgstr "Teammanager"
|
|||
msgid "Team Member"
|
||||
msgstr "Teamlid"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Teamleden"
|
||||
|
|
@ -9632,6 +9905,8 @@ msgid "Team Name"
|
|||
msgstr "Teamnaam"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Team niet gevonden"
|
||||
|
|
@ -9644,6 +9919,10 @@ msgstr "Alleen team"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Team‑only‑sjablonen zijn nergens gekoppeld en alleen zichtbaar voor je team."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr "Teamrol"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9665,6 +9944,7 @@ msgstr "Team-url"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "Team‑URL"
|
||||
|
||||
|
|
@ -9672,6 +9952,7 @@ msgstr "Team‑URL"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9704,6 +9985,7 @@ msgstr "Sjabloon"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Sjabloon (verouderd)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9745,6 +10027,10 @@ msgstr "Sjabloon gebruikt verouderde veldinvoeging"
|
|||
msgid "Template moved"
|
||||
msgstr "Sjabloon verplaatst"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr "Template hernoemd"
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Sjabloon opgeslagen"
|
||||
|
|
@ -10157,6 +10443,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "Het teame-mailadres <0>{teamEmail}</0> is verwijderd uit het volgende team"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "Het team dat u zoekt, is mogelijk verwijderd, hernoemd of heeft misschien nooit bestaan."
|
||||
|
|
@ -10327,6 +10615,10 @@ msgstr "Dit document kan nu niet worden gedupliceerd. Probeer het opnieuw."
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Dit document kan nu niet opnieuw worden verzonden. Probeer het opnieuw."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr "Dit document kan op dit moment niet als sjabloon worden opgeslagen. Probeer het opnieuw."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10385,6 +10677,10 @@ msgstr "Deze e-mail bevestigt dat je het document <0>\"{documentName}\"</0> hebt
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Dit e‑mailadres wordt al door een ander team gebruikt."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr "Deze e-mail wordt naar de documenteigenaar verzonden wanneer een ontvanger een document aanmaakt via een directe sjabloonlink."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Deze e-mail wordt naar de documenteigenaar gestuurd wanneer een ontvanger het document heeft ondertekend."
|
||||
|
|
@ -10562,6 +10858,7 @@ msgstr "Tijdzone"
|
|||
msgid "Time Zone"
|
||||
msgstr "Tijdzone"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10862,6 +11159,10 @@ msgstr "Typ een e-mailadres om een ontvanger toe te voegen"
|
|||
msgid "Type your signature"
|
||||
msgstr "Typ uw handtekening"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr "Getypte handtekening"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Getypte handtekeningen zijn niet toegestaan. Teken je handtekening."
|
||||
|
|
@ -10990,6 +11291,8 @@ msgid "Unknown name"
|
|||
msgstr "Onbekende naam"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Onbeperkt"
|
||||
|
||||
|
|
@ -11235,6 +11538,10 @@ msgstr "Upload documenten en voeg ontvangers toe"
|
|||
msgid "Upload failed"
|
||||
msgstr "Uploaden mislukt"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr "Handtekening uploaden"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Handtekening uploaden"
|
||||
|
|
@ -11322,6 +11629,11 @@ msgstr "User Agent"
|
|||
msgid "User has no password."
|
||||
msgstr "Gebruiker heeft geen wachtwoord."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr "Gebruikers-ID"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Gebruiker niet gevonden"
|
||||
|
|
@ -13007,6 +13319,10 @@ msgstr "Je document is verwijderd door een beheerder!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Je document is succesvol opnieuw verzonden."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr "Je document is opgeslagen als sjabloon."
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Je document is succesvol verzonden."
|
||||
|
|
@ -13015,6 +13331,10 @@ msgstr "Je document is succesvol verzonden."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Je document is succesvol gedupliceerd."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr "Je document is succesvol hernoemd."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr "Je document is succesvol bijgewerkt"
|
||||
|
|
@ -13182,6 +13502,10 @@ msgstr "Je sjabloon is succesvol gedupliceerd."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Je sjabloon is succesvol verwijderd."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr "Je template is succesvol hernoemd."
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr "Je sjabloon is succesvol bijgewerkt"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -847,6 +847,8 @@ msgid "404 Profile not found"
|
|||
msgstr "404 Perfil não encontrado"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "404 Team not found"
|
||||
msgstr "404 Equipe não encontrada"
|
||||
|
|
@ -1010,6 +1012,10 @@ msgstr "Uma URL única para identificar sua organização"
|
|||
msgid "A unique URL to identify your team"
|
||||
msgstr "Uma URL única para identificar sua equipe"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
msgid "A valid email is required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-email-add-dialog.tsx
|
||||
msgid "A verification email will be sent to the provided email."
|
||||
msgstr "Um e-mail de verificação será enviado para o e-mail fornecido."
|
||||
|
|
@ -1386,6 +1392,7 @@ msgstr "Informações adicionais da marca para exibir na parte inferior dos e-ma
|
|||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Admin"
|
||||
|
|
@ -1434,6 +1441,10 @@ msgstr "Após assinar um documento eletronicamente, você terá a oportunidade d
|
|||
msgid "After submission, a document will be automatically generated and added to your documents page. You will also receive a notification via email."
|
||||
msgstr "Após o envio, um documento será gerado automaticamente e adicionado à sua página de documentos. Você também receberá uma notificação por e-mail."
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "AI features"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "AI Features"
|
||||
msgstr "Recursos de IA"
|
||||
|
|
@ -2204,12 +2215,21 @@ msgstr "Detalhes da Marca"
|
|||
msgid "Brand Website"
|
||||
msgstr "Site da Marca"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._layout.tsx
|
||||
msgid "Branding"
|
||||
msgstr "Marca"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding company details"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding logo"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/branding-preferences-form.tsx
|
||||
msgid "Branding Logo"
|
||||
msgstr "Logo da Marca"
|
||||
|
|
@ -2228,6 +2248,10 @@ msgstr "Preferências da Marca"
|
|||
msgid "Branding preferences updated"
|
||||
msgstr "Preferências da marca atualizadas"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Branding URL"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
|
|
@ -2325,6 +2349,8 @@ msgstr ""
|
|||
#: apps/remix/app/components/dialogs/envelope-item-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelopes-bulk-move-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
|
|
@ -2876,8 +2902,8 @@ msgid "Controls how long recipients have to complete signing before the document
|
|||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/email-preferences-form.tsx
|
||||
msgid "Controls the default email settings when new documents or templates are created"
|
||||
msgstr "Controla as configurações padrão de e-mail quando novos documentos ou modelos são criados"
|
||||
msgid "Controls the default email settings when new documents or templates are created. Updating these settings will not affect existing documents or templates."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients."
|
||||
|
|
@ -2939,6 +2965,7 @@ msgstr "Campo copiado para a área de transferência"
|
|||
#: apps/remix/app/components/tables/admin-document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
|
|
@ -2955,6 +2982,10 @@ msgstr "Copiar"
|
|||
msgid "Copy Link"
|
||||
msgstr "Copiar Link"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy organisation ID"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/tables/settings-public-profile-templates-table.tsx
|
||||
msgid "Copy sharable link"
|
||||
msgstr "Copiar link compartilhável"
|
||||
|
|
@ -2968,6 +2999,10 @@ msgstr "Copiar Link Compartilhável"
|
|||
msgid "Copy Signing Links"
|
||||
msgstr "Copiar Links de Assinatura"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Copy team ID"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/token.tsx
|
||||
msgid "Copy token"
|
||||
msgstr "Copiar token"
|
||||
|
|
@ -3010,6 +3045,10 @@ msgstr "Criar um ticket de suporte"
|
|||
msgid "Create a team to collaborate with your team members."
|
||||
msgstr "Crie uma equipe para colaborar com os membros da sua equipe."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Create a template from this document."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/routes/_unauthenticated+/organisation.invite.$token.tsx
|
||||
#: packages/email/template-components/template-document-self-signed.tsx
|
||||
|
|
@ -3187,6 +3226,8 @@ msgstr "Crie sua conta e comece a usar a assinatura de documentos de última ger
|
|||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
|
|
@ -3242,6 +3283,10 @@ msgstr "A senha atual está incorreta."
|
|||
msgid "Current recipients:"
|
||||
msgstr "Destinatários atuais:"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Current usage against organisation limits."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/teams/team-inherit-member-alert.tsx
|
||||
msgid "Currently all organisation members can access this team"
|
||||
msgstr "Atualmente, todos os membros da organização podem acessar esta equipe"
|
||||
|
|
@ -3291,6 +3336,10 @@ msgstr "Data"
|
|||
msgid "Date created"
|
||||
msgstr "Data de criação"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Date format"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -3348,6 +3397,14 @@ msgstr "Função Padrão da Organização para Novos Usuários"
|
|||
msgid "Default Recipients"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Default settings applied to this organisation."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Default settings applied to this team. Inherited values come from the organisation."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Default Signature Settings"
|
||||
msgstr "Configurações de Assinatura Padrão"
|
||||
|
|
@ -3367,6 +3424,10 @@ msgstr ""
|
|||
msgid "Default Value"
|
||||
msgstr "Valor Padrão"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Delegate document ownership"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
|
|
@ -3702,6 +3763,7 @@ msgid "Disable Two Factor Authentication before deleting your account."
|
|||
msgstr "Desative a Autenticação de Dois Fatores antes de excluir sua conta."
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
msgid "Disabled"
|
||||
|
|
@ -3821,6 +3883,7 @@ msgstr "Documento Aprovado"
|
|||
msgid "Document Cancelled"
|
||||
msgstr "Documento Cancelado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document completed"
|
||||
msgstr "Documento concluído"
|
||||
|
|
@ -3865,6 +3928,10 @@ msgstr "Documento criado por <0>{0}</0>"
|
|||
msgid "Document created from direct template"
|
||||
msgstr "Documento criado a partir de modelo direto"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Document created from direct template email"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/template/template-page-view-recent-activity.tsx
|
||||
msgid "Document created using a <0>direct link</0>"
|
||||
msgstr "Documento criado usando um <0>link direto</0>"
|
||||
|
|
@ -3876,6 +3943,7 @@ msgstr "Criação de Documento"
|
|||
#: apps/remix/app/components/dialogs/admin-document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-delete-dialog.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
msgid "Document deleted"
|
||||
msgstr "Documento excluído"
|
||||
|
|
@ -3942,6 +4010,10 @@ msgstr "O documento já foi carregado"
|
|||
msgid "Document is using legacy field insertion"
|
||||
msgstr "O documento está usando inserção de campo legada"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document language"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/tables/templates-table.tsx
|
||||
msgid "Document Limit Exceeded!"
|
||||
msgstr "Limite de Documentos Excedido!"
|
||||
|
|
@ -3968,6 +4040,7 @@ msgctxt "Audit log format"
|
|||
msgid "Document opened"
|
||||
msgstr "Documento aberto"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
msgstr "Documento pendente"
|
||||
|
|
@ -4004,6 +4077,10 @@ msgstr "Documento rejeitado"
|
|||
msgid "Document Rejected"
|
||||
msgstr "Documento Rejeitado"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Document Renamed"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Document sent"
|
||||
msgstr "Documento enviado"
|
||||
|
|
@ -4036,6 +4113,10 @@ msgstr "O processo de assinatura do documento será cancelado"
|
|||
msgid "Document status"
|
||||
msgstr "Status do documento"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Document timezone"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.logs.tsx
|
||||
msgid "Document title"
|
||||
msgstr "Título do documento"
|
||||
|
|
@ -4085,6 +4166,7 @@ msgstr "Documento visualizado"
|
|||
msgid "Document Viewed"
|
||||
msgstr "Documento Visualizado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
|
|
@ -4274,6 +4356,10 @@ msgctxt "Draw signature"
|
|||
msgid "Draw"
|
||||
msgstr "Desenhar"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Draw signature"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-item-edit-dialog.tsx
|
||||
msgid "Drop PDF here or click to select"
|
||||
msgstr ""
|
||||
|
|
@ -4422,7 +4508,7 @@ msgstr "Divulgação de Assinatura Eletrônica"
|
|||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
|
|
@ -4471,6 +4557,10 @@ msgstr "E-mail Confirmado!"
|
|||
msgid "Email Created"
|
||||
msgstr "E-mail Criado"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email document settings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Email Domain"
|
||||
msgstr ""
|
||||
|
|
@ -4532,6 +4622,10 @@ msgstr ""
|
|||
msgid "Email recipients with a signing request"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Email reply-to"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Email resent"
|
||||
|
|
@ -4557,6 +4651,10 @@ msgstr "E-mail enviado!"
|
|||
msgid "Email Settings"
|
||||
msgstr "Configurações de E-mail"
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a document is created from a direct template"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Email the owner when a recipient signs"
|
||||
msgstr ""
|
||||
|
|
@ -4674,6 +4772,7 @@ msgstr ""
|
|||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/site-settings.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
|
|
@ -4712,6 +4811,10 @@ msgstr ""
|
|||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Digite um nome para sua nova pasta. As pastas ajudam você a organizar seus itens."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Enter a new title"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/subscription-claim-form.tsx
|
||||
msgid "Enter claim name"
|
||||
msgstr "Digite o nome da reivindicação"
|
||||
|
|
@ -5169,6 +5272,11 @@ msgstr "Tamanho da fonte do campo"
|
|||
msgid "Field format"
|
||||
msgstr "Formato do campo"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Field ID:"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/editor/editor-field-generic-field-forms.tsx
|
||||
#: apps/remix/app/components/forms/editor/editor-field-text-form.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
|
|
@ -5366,6 +5474,13 @@ msgid "Global recipient action authentication"
|
|||
msgstr "Autenticação de ação de destinatário global"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Global Settings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.email-domains.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -5692,6 +5807,26 @@ msgstr "Caixa de entrada"
|
|||
msgid "Inbox documents"
|
||||
msgstr "Documentos da caixa de entrada"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include audit log"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Fields"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Include Recipients"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include sender details"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Include signing certificate"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Include the Audit Logs in the Document"
|
||||
msgstr "Incluir os Logs de Auditoria no Documento"
|
||||
|
|
@ -5735,6 +5870,10 @@ msgstr "Herdar da organização"
|
|||
msgid "Inherit organisation members"
|
||||
msgstr "Herdar membros da organização"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Inherited"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Inherited subscription claim"
|
||||
|
|
@ -5860,6 +5999,10 @@ msgstr "Convidar membros da equipe para colaborar"
|
|||
msgid "Invite them to the organisation first"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Invited"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-member-invites-table.tsx
|
||||
msgid "Invited At"
|
||||
msgstr "Convidado em"
|
||||
|
|
@ -5929,6 +6072,8 @@ msgid "Join our community on <0>Discord</0> for community support and discussion
|
|||
msgstr "Junte-se à nossa comunidade no <0>Discord</0> para suporte e discussão da comunidade."
|
||||
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Joined"
|
||||
msgstr "Entrou"
|
||||
|
||||
|
|
@ -5937,6 +6082,10 @@ msgstr "Entrou"
|
|||
msgid "Joined {0}"
|
||||
msgstr "Entrou {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Key identifiers and relationships for this team."
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/i18n.ts
|
||||
msgid "Korean"
|
||||
msgstr ""
|
||||
|
|
@ -6247,6 +6396,7 @@ msgstr "Gerenciar contas vinculadas"
|
|||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage organisation"
|
||||
msgstr "Gerenciar organização"
|
||||
|
||||
|
|
@ -6276,6 +6426,10 @@ msgstr "Gerenciar sessões"
|
|||
msgid "Manage subscription"
|
||||
msgstr "Gerenciar assinatura"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage team"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: organisation.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Manage the {0} organisation"
|
||||
|
|
@ -6286,6 +6440,11 @@ msgstr "Gerenciar a organização {0}"
|
|||
msgid "Manage the {0} organisation subscription"
|
||||
msgstr "Gerenciar a assinatura da organização {0}"
|
||||
|
||||
#. placeholder {0}: team.name
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Manage the {0} team"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups._index.tsx
|
||||
msgid "Manage the custom groups of members for your organisation."
|
||||
msgstr "Gerencie os grupos personalizados de membros para sua organização."
|
||||
|
|
@ -6336,6 +6495,7 @@ msgstr "Gerencie as configurações do seu site aqui"
|
|||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Manager"
|
||||
|
|
@ -6391,6 +6551,8 @@ msgstr "Número máximo de arquivos enviados por envelope permitido"
|
|||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: packages/lib/constants/organisations-translations.ts
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Member"
|
||||
|
|
@ -6412,6 +6574,8 @@ msgstr "Membro Desde"
|
|||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -6419,6 +6583,10 @@ msgstr "Membro Desde"
|
|||
msgid "Members"
|
||||
msgstr "Membros"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Members that currently belong to this team."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/support-ticket-form.tsx
|
||||
msgid "Message"
|
||||
msgstr "Mensagem"
|
||||
|
|
@ -6849,6 +7017,10 @@ msgstr "Não encontrado"
|
|||
msgid "Not Found"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Not set"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
msgid "Not supported"
|
||||
msgstr "Não suportado"
|
||||
|
|
@ -6891,6 +7063,14 @@ msgstr "Número de equipes permitidas. 0 = Ilimitado"
|
|||
msgid "Number Settings"
|
||||
msgstr "Configurações de Número"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Off"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "On"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "Nesta página, você pode criar um novo webhook."
|
||||
|
|
@ -7029,6 +7209,10 @@ msgstr "Configurações do Grupo da Organização"
|
|||
msgid "Organisation has been updated successfully"
|
||||
msgstr "A organização foi atualizada com sucesso"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation ID"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisation-insights._index.tsx
|
||||
msgid "Organisation Insights"
|
||||
|
|
@ -7071,6 +7255,7 @@ msgid "Organisation not found"
|
|||
msgstr "Organização não encontrada"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-group-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation role"
|
||||
msgstr "Função na organização"
|
||||
|
||||
|
|
@ -7110,6 +7295,14 @@ msgstr ""
|
|||
msgid "Organisation URL"
|
||||
msgstr "URL da Organização"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Organisation usage"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Organisation-level pending invites for this team's parent organisation."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-desktop.tsx
|
||||
#: apps/remix/app/components/general/settings-nav-mobile.tsx
|
||||
|
|
@ -7161,6 +7354,7 @@ msgstr "Substituir configurações da organização"
|
|||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/unsealed-documents._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
|
|
@ -7169,6 +7363,18 @@ msgstr "Substituir configurações da organização"
|
|||
msgid "Owner"
|
||||
msgstr "Proprietário"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document completed"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner document created"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Owner recipient expired"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
msgid "Ownership transferred to {organisationMemberName}."
|
||||
msgstr "Propriedade transferida para {organisationMemberName}."
|
||||
|
|
@ -7320,6 +7526,10 @@ msgstr ""
|
|||
msgid "Pending invitations"
|
||||
msgstr "Convites pendentes"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Pending Organisation Invites"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/email-domains.$id.tsx
|
||||
msgid "Pending since"
|
||||
msgstr ""
|
||||
|
|
@ -7888,10 +8098,19 @@ msgstr ""
|
|||
msgid "Recipient failed to validate a 2FA token for the document"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page.tsx
|
||||
#: packages/ui/primitives/document-flow/field-item.tsx
|
||||
msgid "Recipient ID:"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "Recipient rejected the document"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient removed"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient removed email"
|
||||
msgstr "E-mail de destinatário removido"
|
||||
|
|
@ -7900,6 +8119,10 @@ msgstr "E-mail de destinatário removido"
|
|||
msgid "Recipient requested a 2FA token for the document"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signed"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signed email"
|
||||
msgstr "E-mail de destinatário assinado"
|
||||
|
|
@ -7908,6 +8131,10 @@ msgstr "E-mail de destinatário assinado"
|
|||
msgid "Recipient signed the document"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Recipient signing request"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "Recipient signing request email"
|
||||
msgstr "E-mail de solicitação de assinatura do destinatário"
|
||||
|
|
@ -8110,6 +8337,21 @@ msgstr "Remover e-mail da equipe"
|
|||
msgid "Remove team member"
|
||||
msgstr "Remover membro da equipe"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
#: apps/remix/app/components/tables/templates-table-action-dropdown.tsx
|
||||
msgid "Rename"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Document"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Rename Template"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/password.tsx
|
||||
#: apps/remix/app/components/forms/reset-password.tsx
|
||||
msgid "Repeat Password"
|
||||
|
|
@ -8360,6 +8602,8 @@ msgstr "Direita"
|
|||
#: apps/remix/app/components/tables/team-groups-table.tsx
|
||||
#: apps/remix/app/components/tables/team-members-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Role"
|
||||
msgstr "Função"
|
||||
|
||||
|
|
@ -8381,6 +8625,15 @@ msgstr "Linhas por página"
|
|||
msgid "Save"
|
||||
msgstr "Salvar"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-dropdown.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
#: apps/remix/app/components/tables/documents-table-action-dropdown.tsx
|
||||
msgid "Save as Template"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
#: packages/lib/client-only/providers/envelope-editor-provider.tsx
|
||||
|
|
@ -9155,6 +9408,7 @@ msgstr "Alguns signatários não receberam um campo de assinatura. Por favor, at
|
|||
#: apps/remix/app/components/dialogs/envelope-download-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-duplicate-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-redistribute-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-invite-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-email-delete-dialog.tsx
|
||||
|
|
@ -9268,6 +9522,10 @@ msgstr "Algo deu errado. Por favor, tente novamente mais tarde."
|
|||
msgid "Something went wrong. Please try again or contact support."
|
||||
msgstr "Algo deu errado. Por favor, tente novamente ou entre em contato com o suporte."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Something went wrong. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document/document-audit-log-download-button.tsx
|
||||
msgid "Sorry, we were unable to download the audit logs. Please try again later."
|
||||
msgstr "Desculpe, não conseguimos baixar os logs de auditoria. Por favor, tente novamente mais tarde."
|
||||
|
|
@ -9552,6 +9810,11 @@ msgstr "Atribuições da Equipe"
|
|||
msgid "Team Count"
|
||||
msgstr "Contagem de Equipes"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team details"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings._index.tsx
|
||||
msgid "Team email"
|
||||
|
|
@ -9574,6 +9837,10 @@ msgstr "O e-mail da equipe foi removido"
|
|||
msgid "Team email has been revoked for {0}"
|
||||
msgstr "O e-mail da equipe foi revogado para {0}"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team email name"
|
||||
msgstr ""
|
||||
|
||||
#: packages/email/templates/team-email-removed.tsx
|
||||
msgid "Team email removed"
|
||||
msgstr "E-mail da equipe removido"
|
||||
|
|
@ -9598,6 +9865,11 @@ msgstr "O e-mail da equipe foi atualizado."
|
|||
msgid "Team Groups"
|
||||
msgstr "Grupos da Equipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team ID"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/teams-translations.ts
|
||||
msgid "Team Manager"
|
||||
msgstr "Gerente da Equipe"
|
||||
|
|
@ -9607,6 +9879,7 @@ msgstr "Gerente da Equipe"
|
|||
msgid "Team Member"
|
||||
msgstr "Membro da Equipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.members.tsx
|
||||
msgid "Team Members"
|
||||
msgstr "Membros da Equipe"
|
||||
|
|
@ -9627,6 +9900,8 @@ msgid "Team Name"
|
|||
msgstr "Nome da Equipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "Team not found"
|
||||
msgstr "Equipe não encontrada"
|
||||
|
|
@ -9639,6 +9914,10 @@ msgstr "Apenas Equipe"
|
|||
msgid "Team only templates are not linked anywhere and are visible only to your team."
|
||||
msgstr "Modelos apenas para equipe não estão vinculados a lugar nenhum e são visíveis apenas para sua equipe."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team role"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-group-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/team-member-create-dialog.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.groups.$id.tsx
|
||||
|
|
@ -9660,6 +9939,7 @@ msgstr "URL da equipe"
|
|||
|
||||
#: apps/remix/app/components/dialogs/team-create-dialog.tsx
|
||||
#: apps/remix/app/components/forms/team-update-form.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "Team URL"
|
||||
msgstr "URL da Equipe"
|
||||
|
||||
|
|
@ -9667,6 +9947,7 @@ msgstr "URL da Equipe"
|
|||
#: apps/remix/app/components/tables/admin-organisation-overview-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/components/tables/organisation-insights-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings._layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.teams.tsx
|
||||
|
|
@ -9699,6 +9980,7 @@ msgstr "Modelo"
|
|||
msgid "Template (Legacy)"
|
||||
msgstr "Modelo (Legado)"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
#: apps/remix/app/routes/embed+/v1+/authoring_.completed.create.tsx
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.create._index.tsx
|
||||
msgid "Template Created"
|
||||
|
|
@ -9740,6 +10022,10 @@ msgstr "O modelo está usando inserção de campo legada"
|
|||
msgid "Template moved"
|
||||
msgstr "Modelo movido"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Template Renamed"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/template/template-edit-form.tsx
|
||||
msgid "Template saved"
|
||||
msgstr "Modelo salvo"
|
||||
|
|
@ -10152,6 +10438,8 @@ msgid "The team email <0>{teamEmail}</0> has been removed from the following tea
|
|||
msgstr "O e-mail da equipe <0>{teamEmail}</0> foi removido da seguinte equipe"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/_layout.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/_layout.tsx
|
||||
msgid "The team you are looking for may have been removed, renamed or may have never existed."
|
||||
msgstr "A equipe que você está procurando pode ter sido removida, renomeada ou nunca ter existido."
|
||||
|
|
@ -10322,6 +10610,10 @@ msgstr "Este documento não pôde ser duplicado neste momento. Por favor, tente
|
|||
msgid "This document could not be re-sent at this time. Please try again."
|
||||
msgstr "Este documento não pôde ser reenviado neste momento. Por favor, tente novamente."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "This document could not be saved as a template at this time. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-recipient-selector.tsx
|
||||
#: packages/ui/primitives/recipient-selector.tsx
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
|
@ -10380,6 +10672,10 @@ msgstr "Este e-mail confirma que você rejeitou o documento <0>\"{documentName}\
|
|||
msgid "This email is already being used by another team."
|
||||
msgstr "Este e-mail já está sendo usado por outra equipe."
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient creates a document via a direct template link."
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/document/document-email-checkboxes.tsx
|
||||
msgid "This email is sent to the document owner when a recipient has signed the document."
|
||||
msgstr "Este e-mail é enviado ao proprietário do documento quando um destinatário assina o documento."
|
||||
|
|
@ -10557,6 +10853,7 @@ msgstr "Fuso horário"
|
|||
msgid "Time Zone"
|
||||
msgstr "Fuso Horário"
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-view.tsx
|
||||
#: apps/remix/app/components/general/template/template-page-view-documents-table.tsx
|
||||
#: apps/remix/app/components/tables/documents-table.tsx
|
||||
|
|
@ -10857,6 +11154,10 @@ msgstr ""
|
|||
msgid "Type your signature"
|
||||
msgstr "Digite sua assinatura"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Typed signature"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-signature-field.tsx
|
||||
msgid "Typed signatures are not allowed. Please draw your signature."
|
||||
msgstr "Assinaturas digitadas não são permitidas. Por favor, desenhe sua assinatura."
|
||||
|
|
@ -10985,6 +11286,8 @@ msgid "Unknown name"
|
|||
msgstr "Nome desconhecido"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-claims-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
msgid "Unlimited"
|
||||
msgstr "Ilimitado"
|
||||
|
||||
|
|
@ -11230,6 +11533,10 @@ msgstr "Envie documentos e adicione destinatários"
|
|||
msgid "Upload failed"
|
||||
msgstr "Falha no envio"
|
||||
|
||||
#: apps/remix/app/components/general/admin-global-settings-section.tsx
|
||||
msgid "Upload signature"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad-upload.tsx
|
||||
msgid "Upload Signature"
|
||||
msgstr "Enviar Assinatura"
|
||||
|
|
@ -11317,6 +11624,11 @@ msgstr "Agente de Usuário"
|
|||
msgid "User has no password."
|
||||
msgstr "O usuário não tem senha."
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations.$id.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/teams.$id.tsx
|
||||
msgid "User ID"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/users.$id.tsx
|
||||
msgid "User not found"
|
||||
msgstr "Usuário não encontrado"
|
||||
|
|
@ -13002,6 +13314,10 @@ msgstr "Seu documento foi excluído por um administrador!"
|
|||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Seu documento foi reenviado com sucesso."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-save-as-template-dialog.tsx
|
||||
msgid "Your document has been saved as a template."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document/document-edit-form.tsx
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Seu documento foi enviado com sucesso."
|
||||
|
|
@ -13010,6 +13326,10 @@ msgstr "Seu documento foi enviado com sucesso."
|
|||
msgid "Your document has been successfully duplicated."
|
||||
msgstr "Seu documento foi duplicado com sucesso."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your document has been successfully renamed."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your document has been updated successfully"
|
||||
msgstr ""
|
||||
|
|
@ -13177,6 +13497,10 @@ msgstr "Seu modelo foi duplicado com sucesso."
|
|||
msgid "Your template has been successfully deleted."
|
||||
msgstr "Seu modelo foi excluído com sucesso."
|
||||
|
||||
#: apps/remix/app/components/dialogs/envelope-rename-dialog.tsx
|
||||
msgid "Your template has been successfully renamed."
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/embed+/v2+/authoring+/envelope.edit.$id.tsx
|
||||
msgid "Your template has been updated successfully"
|
||||
msgstr ""
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue