Compare commits
9 Commits
v1.7.2-rc.
...
feat/save-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb7732a203 | ||
|
|
7ea7740b88 | ||
|
|
ced583a525 | ||
|
|
ca0e96d4c0 | ||
|
|
1d73a0f9e6 | ||
|
|
479131822e | ||
|
|
b885aae511 | ||
|
|
da9287440b | ||
|
|
bed8cbd651 |
48
.cursorrules
48
.cursorrules
@@ -1,48 +0,0 @@
|
||||
Code Style and Structure:
|
||||
- Write concise, technical TypeScript code with accurate examples
|
||||
- Use functional and declarative programming patterns; avoid classes
|
||||
- Prefer iteration and modularization over code duplication
|
||||
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
|
||||
- Structure files: exported component, subcomponents, helpers, static content, types
|
||||
|
||||
Naming Conventions:
|
||||
- Use lowercase with dashes for directories (e.g., components/auth-wizard)
|
||||
- Favor named exports for components
|
||||
|
||||
TypeScript Usage:
|
||||
- Use TypeScript for all code; prefer interfaces over types
|
||||
- Avoid enums; use maps instead
|
||||
- Use functional components with TypeScript interfaces
|
||||
|
||||
Syntax and Formatting:
|
||||
- Use the "function" keyword for pure functions
|
||||
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
|
||||
- Use declarative JSX
|
||||
|
||||
Error Handling and Validation:
|
||||
- Prioritize error handling: handle errors and edge cases early
|
||||
- Use early returns and guard clauses
|
||||
- Implement proper error logging and user-friendly messages
|
||||
- Use Zod for form validation
|
||||
- Model expected errors as return values in Server Actions
|
||||
- Use error boundaries for unexpected errors
|
||||
|
||||
UI and Styling:
|
||||
- Use Shadcn UI, Radix, and Tailwind Aria for components and styling
|
||||
- Implement responsive design with Tailwind CSS; use a mobile-first approach
|
||||
|
||||
Performance Optimization:
|
||||
- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC)
|
||||
- Wrap client components in Suspense with fallback
|
||||
- Use dynamic loading for non-critical components
|
||||
- Optimize images: use WebP format, include size data, implement lazy loading
|
||||
|
||||
Key Conventions:
|
||||
- Use 'nuqs' for URL search parameter state management
|
||||
- Optimize Web Vitals (LCP, CLS, FID)
|
||||
- Limit 'use client':
|
||||
- Favor server components and Next.js SSR
|
||||
- Use only for Web API access in small components
|
||||
- Avoid for data fetching or state management
|
||||
|
||||
Follow Next.js docs for Data Fetching, Rendering, and Routing
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Getting started
|
||||
title: Contributing Guide
|
||||
description: Learn how to contribute to Documenso and become part of our community.
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"index": "Getting Started",
|
||||
"contributing-translations": "Contributing Translations"
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
title: Contributing Translations
|
||||
description: Learn how to contribute translations to Documenso and become part of our community.
|
||||
---
|
||||
|
||||
import { Callout, Steps } from 'nextra/components';
|
||||
|
||||
# Contributing Translations
|
||||
|
||||
We are always open for help with translations! Currently we utilise AI to generate the initial translations for new languages, which are then improved over time by our awesome community.
|
||||
|
||||
If you are looking for development notes on translations, you can find them [here](/developers/local-development/translations).
|
||||
|
||||
<Callout type="info">
|
||||
Contributions are made through GitHub Pull Requests, so you will need a GitHub account to
|
||||
contribute.
|
||||
</Callout>
|
||||
|
||||
## Overview
|
||||
|
||||
We store our translations in PO files, which are located in our GitHub repository [here](https://github.com/documenso/documenso/tree/main/packages/lib/translations).
|
||||
|
||||
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc). Each language folder contains three PO files:
|
||||
|
||||
1. `web.po`: Translations for the web application
|
||||
2. `marketing.po`: Translations for the marketing application
|
||||
3. `common.po`: Shared translations between web and marketing
|
||||
|
||||
Each PO file contains translations which look like this:
|
||||
|
||||
```po
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:61
|
||||
msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
|
||||
msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüfen Sie Documenso.</0>"
|
||||
```
|
||||
|
||||
- `msgid`: The original text in English (never edit this manually)
|
||||
- `msgstr`: The translated text in the target language
|
||||
|
||||
<Callout type="warning">
|
||||
Notice the `<0>` tags? These represent HTML elements and must remain in both the `msgid` and `msgstr`. Make sure to translate the content between these tags while keeping the tags intact.
|
||||
</Callout>
|
||||
|
||||
## How to Contribute
|
||||
|
||||
### Updating Existing Translations
|
||||
|
||||
1. Fork the repository.
|
||||
2. Navigate to the appropriate language folder.
|
||||
3. Open the PO file you want to update (web.po, marketing.po, or common.po).
|
||||
4. Make your changes, ensuring you follow the PO file format.
|
||||
5. Commit your changes with a message such as `chore: update German translations`
|
||||
6. Create a Pull Request.
|
||||
|
||||
### Adding a New Language
|
||||
|
||||
If you want to add translations for a language that doesn't exist yet:
|
||||
|
||||
1. Create an issue in our GitHub repository requesting the addition of the new language.
|
||||
2. Wait for our team to review and approve the request.
|
||||
3. Once approved, we will set up the necessary files and kickstart the translations with AI to provide initial coverage.
|
||||
|
||||
## Need Help?
|
||||
|
||||
<Callout type="info">
|
||||
If you have any questions, hop into our [Discord](https://documen.so/discord) and ask us directly!
|
||||
</Callout>
|
||||
|
||||
Thank you for helping make Documenso more accessible to users around the world!
|
||||
@@ -10,7 +10,6 @@
|
||||
"signing-documents": "Signing Documents",
|
||||
"templates": "Templates",
|
||||
"direct-links": "Direct Signing Links",
|
||||
"document-visibility": "Document Visibility",
|
||||
"-- Legal Overview": {
|
||||
"type": "separator",
|
||||
"title": "Legal Overview"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
title: Document Visibility
|
||||
description: Learn how to control the visibility of your team documents.
|
||||
---
|
||||
|
||||
# Team's Document Visibility
|
||||
|
||||
By default, all documents created in a team are visible to all team members. However, you can control the visibility of your documents by changing the document's visibility settings.
|
||||
|
||||
To set the visibility of a document, click on the **Document visibility** dropdown in the document's settings panel.
|
||||
|
||||

|
||||
|
||||
The document visibility can be set to one of the following options:
|
||||
|
||||
- **Everyone** - The document is visible to all team members.
|
||||
- **Managers and above** - The document is visible to people with the role of Manager or above.
|
||||
- **Admin only** - The document is only visible to the team's admins.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: 'Customer Story Prisma: 4 Reasons why Prisma chose Documenso for Signatures'
|
||||
description: We are happy to welcome Prisma, another OSS company, as a customer. Read here why they choose us.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-09-26
|
||||
tags:
|
||||
- Prisma
|
||||
- Customer Story
|
||||
- Open Source
|
||||
---
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/prisma.png"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="Primsa Landing Page We simplify database migration, connection pooling, database queries, and readable data models."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Prisma uses Documenso for collaborative team signing.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
> TLDR; Prisma is now using Documenso, and [we added visibility scopes](https://docs.documenso.com/users/document-visibility)
|
||||
|
||||
# Prisma
|
||||
|
||||
Prisma is an open-source company known for its modern OSS ORM (Object-Relational Mapping) tools that simplify database interactions for developers. Their flagship product, Prisma ORM, provides a type-safe way to query databases like PostgreSQL, MySQL, and many more. With the addition of Prisma Studio, an intuitive database management interface, Prisma makes it easier and more efficient for developers to work with databases. With their new additions, Prisma Pulse and Accelerate, you can react to real-time database changes and optimize your queries. And they are completely [open source](https://github.com/prisma/prisma)!
|
||||
|
||||
# We choose Prisma too!
|
||||
|
||||
I discovered Prisma when planning the tech stack for the [first version of Documenso](https://github.com/documenso/documenso/releases/tag/0.9-developer-preview). Prisma has felt natural to use since day one and has been the base of our database architecture ever since. It's great to see them develop and grow with us.
|
||||
|
||||
# Why they choose us
|
||||
|
||||
## 1. Signature Flows
|
||||
|
||||
Documenso signing flows are highly configurable, designed to adapt to the needs of any document signing process. Whether you're working with different roles, varying settings, or specific delivery methods, Documenso offers the flexibility to suit your requirements. You can choose to send documents via email, share a manual link, generate a link through the API, or even use a static direct link for quick access—all while ensuring a smooth signing experience.
|
||||
|
||||
Additionally, you can create templates to streamline and reuse common workflows, saving valuable time. Direct link templates enable users to drive the flow themselves, providing a straightforward path for signing. For a seamless experience, Documenso also allows you to embed the signing process directly into your website, ensuring an uninterrupted, integrated workflow tailored to your needs.
|
||||
|
||||
## 2. Modern UX
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/dsux.png"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="A completed document in Documenso, ready to download."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
We call Documenso's design "Happy Minimalism"
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
We’ve crafted Documenso with a sleek, modern interface that makes it incredibly easy to use. Whether you’re signing documents, managing workflows, or fine-tuning settings, its intuitive design allows you to accomplish tasks quickly and effortlessly. More than just powerful, Documenso is a pleasure to navigate—designed to be accessible to everyone, no matter their level of tech experience.
|
||||
|
||||
## 3. Teams
|
||||
|
||||
### Teamwork Makes the Dream Work
|
||||
|
||||
Documenso makes teamwork a breeze with its team management features. You can easily set up and organize teams, making it simple to share and manage documents and workflows together. This is a lifesaver for larger organizations or teams spread across different departments, ensuring everyone stays in sync and on track. Different visibility scopes ensure private documents stay private and others are shared for easy collaboration.
|
||||
|
||||
### Document Visibility
|
||||
|
||||
Collaboration within a team often demands different levels of access to documents. For instance, the Documenso team at Prisma needed a way to set custom visibility on some documents while keeping others accessible to everyone. To address this need, we introduced role-based visibility scopes. This feature allows teams to manage documents more effectively. They can make certain documents visible only to managers or, in special cases, restricted to admins. This ensures sensitive information stays protected while general documents remain accessible to those who need them.
|
||||
|
||||
Learn more about visibility scopes and [how they can benefit your team here](https://docs.documenso.com/users/document-visibility).
|
||||
|
||||
## 4. OSS!
|
||||
|
||||
As you might know, we are open-source! This means you can peek under the hood, tweak things to your liking, and even contribute to making the platform better. We love the community-driven aspect of open-source, and it aligns perfectly with our goal to keep improving and innovating with input from our users.
|
||||
|
||||
So, whether you're looking to streamline your document workflows or just need a solid, reliable platform, Documenso has got your back. And we're thrilled to serve another OSS company and help make the space more open.
|
||||
|
||||
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
Thinking about switching to a modern signing platform? Reach out anytime: [https://documen.so/sales](https://documen.so/sales)
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
title: Go Fork Yourself
|
||||
description: Curious about our take on open-source and code forking? Discover why we see forking not as a threat but as a vital part of the Open Source ecosystem.
|
||||
authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-10-03
|
||||
tags:
|
||||
- Culture
|
||||
- Open Startup
|
||||
- Open Source
|
||||
---
|
||||
|
||||
> TLDR; At Documenso, we see OSS as co-owned by all. Forking—collaborative or not—is part of the open-source spirit.
|
||||
|
||||
## Freedom vs. Ownership
|
||||
|
||||
Recently, there has been a lot of debate on the subject of forks and the usage of OSS IP (Open Source Software Intellectual Property). While I mostly aim to stay out of these controversies (as there is no “winning”), I wanted to take this opportunity to share my views on IP and forking culture here at Documenso. I don’t presume this is the ideal path, but for me, it’s the only path that makes sense.
|
||||
|
||||
What these issues show foremost, in my opinion, is that the concept of Open Source is still evolving. I have heard many say, “Open Source is clearly defined” and that there is no ambiguity anymore. That may be true on the legal side, but there are vast differences in how these rules are interpreted and lived out. Here are a few questions to illustrate the point:
|
||||
|
||||
1. Is it okay to use an open-source project without ever giving back?
|
||||
2. Is it okay to fork (some might say copy) an OSS product and build something on top of it?
|
||||
3. Are we morally obliged to fight those who provide different answers to these questions than we do?
|
||||
|
||||
## Embracing Forks and Collaboration
|
||||
|
||||
Since starting Documenso, I’ve thought a lot about what it actually means to be Open Source for us. So far, it has been about openness in working with everyone, from contributors to customers and sharing our work transparently. For this, we have been richly rewarded with attention and reach. This collaborative give-and-take is what people commonly associate with being Open Source, and it seems ideal.
|
||||
|
||||
Yet, there are the questions mentioned above. And while these may be contentious, my take is straightforward:
|
||||
|
||||
1. Yes.
|
||||
2. Yes.
|
||||
3. No.
|
||||
|
||||
I say this because, to me, the principles of Open Source are rooted in freedom and collaboration. That means allowing others to use, improve, or even compete with what you’ve built without feeling possessive over the code. The beauty of Open Source lies in its openness—its ability to be forked, reused, and adapted by anyone.
|
||||
|
||||
You may answer these questions differently for your own reasons. One thing I’ve found lacking in the discourse is the fact that Open Source is still being treated as socially proprietary. If it’s under an open-source license, you can fork it and try to improve upon the original, and there’s nothing wrong with that. The same is true for closed-source startups. Yet in Open Source, there’s a notion that it’s somehow “dirty,” even though the license explicitly allows it.
|
||||
|
||||
## Forking in Action: Real-World Examples
|
||||
|
||||
When the team behind **Node.js** disagreed with its governance and pace of development, they forked the project to create **io.js**. This wasn’t seen as dirty but as a necessary push for change. In fact, the fork resulted in positive changes—better community governance and faster development—which eventually led to the merge of the two projects under the Node.js Foundation. It shows that forking can be a catalyst for improvement, not just competition.
|
||||
|
||||
## The Misconception of “Exploitative” Usage
|
||||
|
||||
However, sometimes forks don’t merge back but still bring positive change. A good example is **Jenkins**, which was forked from **Hudson** over disagreements in governance after Oracle acquired Sun Microsystems. Jenkins quickly overtook Hudson in terms of community support, development, and innovation. Rather than being seen as a hostile move, the fork enabled Jenkins to become a thriving project, better aligned with the open-source ethos of collaboration and transparency. It emphasizes that forking isn’t inherently exploitative; it can simply be a way to realize a project’s full potential.
|
||||
|
||||
And then there’s **MariaDB**, a fork of **MySQL**. After Oracle acquired MySQL, many in the community feared the project’s open-source nature could be compromised. The fork preserved its spirit, and MariaDB has since grown to become a popular and thriving database. It’s a reminder that sometimes, forking is not just acceptable—it’s necessary to uphold the values and freedoms of open-source software.
|
||||
|
||||
<figure>
|
||||
<MdxNextImage
|
||||
src="/blog/owncode.jpeg"
|
||||
width="1200"
|
||||
height="675"
|
||||
alt="Meme: If everyone owns the code, no one does."
|
||||
/>
|
||||
|
||||
<figcaption className="text-center">
|
||||
Funny Meme to drive the point home.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
My view is that the code is not “your” code, just as Documenso’s code is not “our” code. It’s been co-owned by the world ever since we published the repo under AGPL V3. That is the whole point. It’s finally not owned by anyone (cue the “everyone/no one” meme). Open Source is for everyone, even competitors. Yet, we are still treating the licenses as extensions of the old, proprietary world and defending perceived injustices based on that model.
|
||||
|
||||
> Side Note: Full compliance with all license and other legal rules is a given here.
|
||||
|
||||
## Documenso’s Approach: Co-Ownership and Community
|
||||
|
||||
So, if you want to fork Documenso and build a business on it, you can. Whether that’s a cool thing to do is another matter. Whether you do a better job than us is also another matter (you won’t). But if you do, I’ll be the first to join. But why not join us from the start since you already have the upside? We exist because we believe this to be the best way forward—not because we force it.
|
||||
|
||||
## The Bigger Picture: Open-Source as Progress
|
||||
|
||||
I’ve also thought a lot about question #3. I understand the impulse to fight anyone who doesn’t appreciate this collaborative approach, but there is no part of this model that backs that up. You are free to “exploit” as long as it’s in a way that adds value. The fallacy is in considering someone else using the OSS part for their business as treason, which it’s not. It’s the whole point.
|
||||
|
||||
While some might say this is theoretical and that reality is different, this is the version of Open Source on which we are building Documenso. The point here is that OSS companies must be resilient to handle forking and competition; without this resilience, an open source driven economy can’t thrive. The focus on freedom and collaboration means being prepared for forks and challenges as part of the growth, not as threats.
|
||||
|
||||
Of course, all of this applies to Documenso, the OSS project, not Documenso Inc., the company, which is very much a privately owned, for-profit entity. However, since the goal is to scale Documenso to the entire world, there is plenty of room to see everyone as co-owners of the Open Source project rather than as competitors. In the end, Open Source is about progress through freedom. If you don’t like how we run things, go fork yourself and hold us accountable. We don’t own this; we just happened to start it.
|
||||
|
||||
> Since this article is open source as well, you are free to fork it and change it here: [https://documen.so/repo](https://documen.so/repo)
|
||||
|
||||
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
|
||||
|
||||
Thinking about switching to a modern signing platform? Reach out anytime: [https://documen.so/sales](https://documen.so/sales)
|
||||
|
||||
Best from Hamburg\
|
||||
Timur
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@documenso/marketing",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
@@ -34,7 +34,7 @@
|
||||
"micro": "^10.0.1",
|
||||
"next": "14.2.6",
|
||||
"next-auth": "4.24.5",
|
||||
"next-axiom": "^1.5.1",
|
||||
"next-axiom": "^1.1.1",
|
||||
"next-contentlayer": "^0.3.4",
|
||||
"next-plausible": "^3.10.1",
|
||||
"perfect-freehand": "^1.2.0",
|
||||
|
||||
4
apps/marketing/process-env.d.ts
vendored
4
apps/marketing/process-env.d.ts
vendored
@@ -2,8 +2,8 @@ declare namespace NodeJS {
|
||||
export interface ProcessEnv {
|
||||
NEXT_PUBLIC_WEBAPP_URL?: string;
|
||||
NEXT_PUBLIC_MARKETING_URL?: string;
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string;
|
||||
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?: string;
|
||||
|
||||
NEXT_PRIVATE_DATABASE_URL: string;
|
||||
|
||||
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID: string;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 692 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 435 KiB |
@@ -19,10 +19,10 @@ export const TEAM_MEMBERS = [
|
||||
},
|
||||
{
|
||||
name: 'Ephraim Atta-Duncan',
|
||||
role: 'Software Engineer - I',
|
||||
salary: 60_000,
|
||||
role: 'Software Engineer - Intern',
|
||||
salary: 15_000,
|
||||
location: 'Ghana',
|
||||
engagement: msg`Full-Time`,
|
||||
engagement: msg`Part-Time`,
|
||||
joinDate: 'June 6th, 2023',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -168,7 +168,6 @@ export const SinglePlayerClient = () => {
|
||||
sendStatus: 'NOT_SENT',
|
||||
role: 'SIGNER',
|
||||
authOptions: null,
|
||||
signingOrder: null,
|
||||
};
|
||||
|
||||
const onFileDrop = async (file: File) => {
|
||||
|
||||
@@ -108,21 +108,14 @@ export const Carousel = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const newIndex = emblaApi.selectedScrollSnap();
|
||||
|
||||
setSelectedIndex(newIndex);
|
||||
emblaThumbsApi.scrollTo(newIndex);
|
||||
setSelectedIndex(emblaApi.selectedScrollSnap());
|
||||
emblaThumbsApi.scrollTo(emblaApi.selectedScrollSnap());
|
||||
|
||||
resetProgress();
|
||||
|
||||
const currentVideo = videoRefs.current[newIndex];
|
||||
if (currentVideo) {
|
||||
currentVideo.currentTime = 0;
|
||||
}
|
||||
|
||||
// moduleResolution: bundler breaks this type
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const autoplay = emblaApi?.plugins()?.autoplay as unknown as AutoplayType | undefined;
|
||||
const autoplay = emblaApi.plugins()?.autoplay as unknown as AutoplayType | undefined;
|
||||
|
||||
if (autoplay) {
|
||||
autoplay.reset();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@documenso/web",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
@@ -37,7 +37,7 @@
|
||||
"micro": "^10.0.1",
|
||||
"next": "14.2.6",
|
||||
"next-auth": "4.24.5",
|
||||
"next-axiom": "^1.5.1",
|
||||
"next-axiom": "^1.1.1",
|
||||
"next-plausible": "^3.10.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"papaparse": "^5.4.1",
|
||||
@@ -53,7 +53,7 @@
|
||||
"react-icons": "^4.11.0",
|
||||
"react-rnd": "^10.4.1",
|
||||
"recharts": "^2.7.2",
|
||||
"remeda": "^2.12.1",
|
||||
"remeda": "^1.27.1",
|
||||
"sharp": "0.32.6",
|
||||
"ts-pattern": "^5.0.5",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
|
||||
2
apps/web/process-env.d.ts
vendored
2
apps/web/process-env.d.ts
vendored
@@ -2,7 +2,7 @@ declare namespace NodeJS {
|
||||
export interface ProcessEnv {
|
||||
NEXT_PUBLIC_WEBAPP_URL?: string;
|
||||
NEXT_PUBLIC_MARKETING_URL?: string;
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string;
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL?: string;
|
||||
|
||||
NEXT_PRIVATE_DATABASE_URL: string;
|
||||
|
||||
|
||||
@@ -12,12 +12,10 @@ import { getDocumentById } from '@documenso/lib/server-only/document/get-documen
|
||||
import { getServerComponentFlag } from '@documenso/lib/server-only/feature-flags/get-server-component-feature-flag';
|
||||
import { getFieldsForDocument } from '@documenso/lib/server-only/field/get-fields-for-document';
|
||||
import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document';
|
||||
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
||||
import { symmetricDecrypt } from '@documenso/lib/universal/crypto';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import type { Team, TeamEmail } from '@documenso/prisma/client';
|
||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||
import { Badge } from '@documenso/ui/primitives/badge';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||
@@ -41,7 +39,7 @@ export type DocumentPageViewProps = {
|
||||
params: {
|
||||
id: string;
|
||||
};
|
||||
team?: Team & { teamEmail: TeamEmail | null } & { currentTeamMember: { role: TeamMemberRole } };
|
||||
team?: Team & { teamEmail: TeamEmail | null };
|
||||
};
|
||||
|
||||
export const DocumentPageView = async ({ params, team }: DocumentPageViewProps) => {
|
||||
@@ -64,35 +62,11 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
|
||||
teamId: team?.id,
|
||||
}).catch(() => null);
|
||||
|
||||
if (document?.teamId && !team?.url) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
const documentVisibility = document?.visibility;
|
||||
const currentTeamMemberRole = team?.currentTeamMember?.role;
|
||||
const isRecipient = document?.Recipient.find((recipient) => recipient.email === user.email);
|
||||
let canAccessDocument = true;
|
||||
|
||||
if (team && !isRecipient) {
|
||||
canAccessDocument = match([documentVisibility, currentTeamMemberRole])
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.ADMIN], () => true)
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.MANAGER], () => true)
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.MEMBER], () => true)
|
||||
.with([DocumentVisibility.MANAGER_AND_ABOVE, TeamMemberRole.ADMIN], () => true)
|
||||
.with([DocumentVisibility.MANAGER_AND_ABOVE, TeamMemberRole.MANAGER], () => true)
|
||||
.with([DocumentVisibility.ADMIN, TeamMemberRole.ADMIN], () => true)
|
||||
.otherwise(() => false);
|
||||
}
|
||||
|
||||
const isDocumentHistoryEnabled = await getServerComponentFlag(
|
||||
'app_document_page_view_history_sheet',
|
||||
);
|
||||
|
||||
if (!document || !document.documentData || (team && !canAccessDocument)) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
if (team && !canAccessDocument) {
|
||||
if (!document || !document.documentData) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,20 +85,6 @@ export const EditDocumentForm = ({
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: setSigningOrderForDocument } =
|
||||
trpc.document.setSigningOrderForDocument.useMutation({
|
||||
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||
onSuccess: (newData) => {
|
||||
utils.document.getDocumentWithDetailsById.setData(
|
||||
{
|
||||
id: initialDocument.id,
|
||||
teamId: team?.id,
|
||||
},
|
||||
(oldData) => ({ ...(oldData || initialDocument), ...newData, id: Number(newData.id) }),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: addFields } = trpc.field.addFields.useMutation({
|
||||
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||
onSuccess: (newFields) => {
|
||||
@@ -191,7 +177,6 @@ export const EditDocumentForm = ({
|
||||
data: {
|
||||
title: data.title,
|
||||
externalId: data.externalId || null,
|
||||
visibility: data.visibility,
|
||||
globalAccessAuth: data.globalAccessAuth ?? null,
|
||||
globalActionAuth: data.globalActionAuth ?? null,
|
||||
},
|
||||
@@ -219,22 +204,15 @@ export const EditDocumentForm = ({
|
||||
|
||||
const onAddSignersFormSubmit = async (data: TAddSignersFormSchema) => {
|
||||
try {
|
||||
await Promise.all([
|
||||
setSigningOrderForDocument({
|
||||
documentId: document.id,
|
||||
signingOrder: data.signingOrder,
|
||||
}),
|
||||
|
||||
addSigners({
|
||||
documentId: document.id,
|
||||
teamId: team?.id,
|
||||
signers: data.signers.map((signer) => ({
|
||||
...signer,
|
||||
// Explicitly set to null to indicate we want to remove auth if required.
|
||||
actionAuth: signer.actionAuth || null,
|
||||
})),
|
||||
}),
|
||||
]);
|
||||
await addSigners({
|
||||
documentId: document.id,
|
||||
teamId: team?.id,
|
||||
signers: data.signers.map((signer) => ({
|
||||
...signer,
|
||||
// Explicitly set to null to indicate we want to remove auth if required.
|
||||
actionAuth: signer.actionAuth || null,
|
||||
})),
|
||||
});
|
||||
|
||||
// Router refresh is here to clear the router cache for when navigating to /documents.
|
||||
router.refresh();
|
||||
@@ -361,7 +339,6 @@ export const EditDocumentForm = ({
|
||||
key={recipients.length}
|
||||
documentFlow={documentFlow.settings}
|
||||
document={document}
|
||||
currentTeamMemberRole={team?.currentTeamMember?.role}
|
||||
recipients={recipients}
|
||||
fields={fields}
|
||||
isDocumentEnterprise={isDocumentEnterprise}
|
||||
@@ -372,12 +349,13 @@ export const EditDocumentForm = ({
|
||||
<AddSignersFormPartial
|
||||
key={recipients.length}
|
||||
documentFlow={documentFlow.signers}
|
||||
document={document}
|
||||
recipients={recipients}
|
||||
signingOrder={document.documentMeta?.signingOrder}
|
||||
fields={fields}
|
||||
isDocumentEnterprise={isDocumentEnterprise}
|
||||
onSubmit={onAddSignersFormSubmit}
|
||||
isDocumentPdfLoaded={isDocumentPdfLoaded}
|
||||
teamId={team?.id}
|
||||
/>
|
||||
|
||||
<AddFieldsFormPartial
|
||||
|
||||
@@ -3,17 +3,14 @@ import { redirect } from 'next/navigation';
|
||||
|
||||
import { Plural, Trans } from '@lingui/macro';
|
||||
import { ChevronLeft, Users2 } from 'lucide-react';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto';
|
||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||
import { getDocumentWithDetailsById } from '@documenso/lib/server-only/document/get-document-with-details-by-id';
|
||||
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
||||
import { symmetricDecrypt } from '@documenso/lib/universal/crypto';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import type { Team } from '@documenso/prisma/client';
|
||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||
import { DocumentStatus as InternalDocumentStatus } from '@documenso/prisma/client';
|
||||
|
||||
import { EditDocumentForm } from '~/app/(dashboard)/documents/[id]/edit-document';
|
||||
@@ -24,7 +21,7 @@ export type DocumentEditPageViewProps = {
|
||||
params: {
|
||||
id: string;
|
||||
};
|
||||
team?: Team & { currentTeamMember: { role: TeamMemberRole } };
|
||||
team?: Team;
|
||||
};
|
||||
|
||||
export const DocumentEditPageView = async ({ params, team }: DocumentEditPageViewProps) => {
|
||||
@@ -46,34 +43,10 @@ export const DocumentEditPageView = async ({ params, team }: DocumentEditPageVie
|
||||
teamId: team?.id,
|
||||
}).catch(() => null);
|
||||
|
||||
if (document?.teamId && !team?.url) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
const documentVisibility = document?.visibility;
|
||||
const currentTeamMemberRole = team?.currentTeamMember?.role;
|
||||
const isRecipient = document?.Recipient.find((recipient) => recipient.email === user.email);
|
||||
let canAccessDocument = true;
|
||||
|
||||
if (!isRecipient) {
|
||||
canAccessDocument = match([documentVisibility, currentTeamMemberRole])
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.ADMIN], () => true)
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.MANAGER], () => true)
|
||||
.with([DocumentVisibility.EVERYONE, TeamMemberRole.MEMBER], () => true)
|
||||
.with([DocumentVisibility.MANAGER_AND_ABOVE, TeamMemberRole.ADMIN], () => true)
|
||||
.with([DocumentVisibility.MANAGER_AND_ABOVE, TeamMemberRole.MANAGER], () => true)
|
||||
.with([DocumentVisibility.ADMIN, TeamMemberRole.ADMIN], () => true)
|
||||
.otherwise(() => false);
|
||||
}
|
||||
|
||||
if (!document) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
if (team && !canAccessDocument) {
|
||||
redirect(documentRootPath);
|
||||
}
|
||||
|
||||
if (document.status === InternalDocumentStatus.COMPLETED) {
|
||||
redirect(`${documentRootPath}/${documentId}`);
|
||||
}
|
||||
|
||||
@@ -10,13 +10,12 @@ import type { GetStatsInput } from '@documenso/lib/server-only/document/get-stat
|
||||
import { getStats } from '@documenso/lib/server-only/document/get-stats';
|
||||
import { parseToIntegerArray } from '@documenso/lib/utils/params';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import type { Team, TeamEmail, TeamMemberRole } from '@documenso/prisma/client';
|
||||
import type { Team, TeamEmail } from '@documenso/prisma/client';
|
||||
import { isExtendedDocumentStatus } from '@documenso/prisma/guards/is-extended-document-status';
|
||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@documenso/ui/primitives/avatar';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@documenso/ui/primitives/tabs';
|
||||
|
||||
import { DocumentSearch } from '~/components/(dashboard)/document-search/document-search';
|
||||
import { PeriodSelector } from '~/components/(dashboard)/period-selector/period-selector';
|
||||
import { isPeriodSelectorValue } from '~/components/(dashboard)/period-selector/types';
|
||||
import { DocumentStatus } from '~/components/formatter/document-status';
|
||||
@@ -26,17 +25,16 @@ import { DataTableSenderFilter } from './data-table-sender-filter';
|
||||
import { EmptyDocumentState } from './empty-state';
|
||||
import { UploadDocument } from './upload-document';
|
||||
|
||||
export interface DocumentsPageViewProps {
|
||||
export type DocumentsPageViewProps = {
|
||||
searchParams?: {
|
||||
status?: ExtendedDocumentStatus;
|
||||
period?: PeriodSelectorValue;
|
||||
page?: string;
|
||||
perPage?: string;
|
||||
senderIds?: string;
|
||||
search?: string;
|
||||
};
|
||||
team?: Team & { teamEmail?: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
|
||||
}
|
||||
team?: Team & { teamEmail?: TeamEmail | null };
|
||||
};
|
||||
|
||||
export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPageViewProps) => {
|
||||
const { user } = await getRequiredServerComponentSession();
|
||||
@@ -46,16 +44,13 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
||||
const page = Number(searchParams.page) || 1;
|
||||
const perPage = Number(searchParams.perPage) || 20;
|
||||
const senderIds = parseToIntegerArray(searchParams.senderIds ?? '');
|
||||
const search = searchParams.search || '';
|
||||
const currentTeam = team
|
||||
? { id: team.id, url: team.url, teamEmail: team.teamEmail?.email }
|
||||
: undefined;
|
||||
const currentTeamMemberRole = team?.currentTeamMember?.role;
|
||||
|
||||
const getStatOptions: GetStatsInput = {
|
||||
user,
|
||||
period,
|
||||
search,
|
||||
};
|
||||
|
||||
if (team) {
|
||||
@@ -63,9 +58,6 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
||||
teamId: team.id,
|
||||
teamEmail: team.teamEmail?.email,
|
||||
senderIds,
|
||||
currentTeamMemberRole,
|
||||
currentUserEmail: user.email,
|
||||
userId: user.id,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,7 +75,6 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
||||
perPage,
|
||||
period,
|
||||
senderIds,
|
||||
search,
|
||||
});
|
||||
|
||||
const getTabHref = (value: typeof status) => {
|
||||
@@ -140,7 +131,10 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
||||
<DocumentStatus status={value} />
|
||||
|
||||
{value !== ExtendedDocumentStatus.ALL && (
|
||||
<span className="ml-1 inline-block opacity-50">{stats[value]}</span>
|
||||
<span className="ml-1 inline-block opacity-50">
|
||||
{Math.min(stats[value], 99)}
|
||||
{stats[value] > 99 && '+'}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
</TabsTrigger>
|
||||
@@ -153,9 +147,6 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
|
||||
<div className="flex w-48 flex-wrap items-center justify-between gap-x-2 gap-y-4">
|
||||
<PeriodSelector />
|
||||
</div>
|
||||
<div className="flex w-48 flex-wrap items-center justify-between gap-x-2 gap-y-4">
|
||||
<DocumentSearch initialValue={search} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export const UserPasskeysDataTable = () => {
|
||||
cell: ({ row }) =>
|
||||
row.original.lastUsedAt
|
||||
? DateTime.fromJSDate(row.original.lastUsedAt).toRelative()
|
||||
: _(msg`Never`),
|
||||
: msg`Never`,
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
|
||||
@@ -103,19 +103,6 @@ export const EditTemplateForm = ({
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: setSigningOrderForTemplate } =
|
||||
trpc.template.setSigningOrderForTemplate.useMutation({
|
||||
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||
onSuccess: (newData) => {
|
||||
utils.template.getTemplateWithDetailsById.setData(
|
||||
{
|
||||
id: initialTemplate.id,
|
||||
},
|
||||
(oldData) => ({ ...(oldData || initialTemplate), ...newData }),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: addTemplateFields } = trpc.field.addTemplateFields.useMutation({
|
||||
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
|
||||
onSuccess: (newData) => {
|
||||
@@ -173,19 +160,11 @@ export const EditTemplateForm = ({
|
||||
data: TAddTemplatePlacholderRecipientsFormSchema,
|
||||
) => {
|
||||
try {
|
||||
await Promise.all([
|
||||
setSigningOrderForTemplate({
|
||||
templateId: template.id,
|
||||
teamId: team?.id,
|
||||
signingOrder: data.signingOrder,
|
||||
}),
|
||||
|
||||
addTemplateSigners({
|
||||
templateId: template.id,
|
||||
teamId: team?.id,
|
||||
signers: data.signers,
|
||||
}),
|
||||
]);
|
||||
await addTemplateSigners({
|
||||
templateId: template.id,
|
||||
teamId: team?.id,
|
||||
signers: data.signers,
|
||||
});
|
||||
|
||||
// Router refresh is here to clear the router cache for when navigating to /documents.
|
||||
router.refresh();
|
||||
@@ -283,11 +262,11 @@ export const EditTemplateForm = ({
|
||||
documentFlow={documentFlow.signers}
|
||||
recipients={recipients}
|
||||
fields={fields}
|
||||
signingOrder={template.templateMeta?.signingOrder}
|
||||
templateDirectLink={template.directLink}
|
||||
onSubmit={onAddTemplatePlaceholderFormSubmit}
|
||||
isEnterprise={isEnterprise}
|
||||
isDocumentPdfLoaded={isDocumentPdfLoaded}
|
||||
template={template}
|
||||
/>
|
||||
|
||||
<AddTemplateFieldsFormPartial
|
||||
|
||||
@@ -267,14 +267,14 @@ export const CheckboxField = ({
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<div className="flex flex-col gap-y-1">
|
||||
<div className="flex flex-col gap-y-2">
|
||||
{values?.map((item: { id: number; value: string; checked: boolean }, index: number) => {
|
||||
const itemValue = item.value || `empty-value-${item.id}`;
|
||||
|
||||
return (
|
||||
<div key={index} className="flex items-center gap-x-1.5">
|
||||
<Checkbox
|
||||
className="h-3 w-3"
|
||||
className="h-4 w-4"
|
||||
checkClassName="text-white"
|
||||
id={`checkbox-${index}`}
|
||||
checked={field.customText
|
||||
@@ -283,7 +283,7 @@ export const CheckboxField = ({
|
||||
disabled={isLoading}
|
||||
onCheckedChange={() => void handleCheckboxOptionClick(item)}
|
||||
/>
|
||||
<Label htmlFor={`checkbox-${index}`} className="text-xs">
|
||||
<Label htmlFor={`checkbox-${index}`}>
|
||||
{item.value.includes('empty-value-') ? '' : item.value}
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
@@ -204,29 +204,25 @@ export default async function CompletedSigningPage({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center">
|
||||
{canSignUp && (
|
||||
<div className="flex max-w-xl flex-col items-center justify-center p-4 md:p-12">
|
||||
<h2 className="mt-8 text-center text-xl font-semibold md:mt-0">
|
||||
<Trans>Need to sign documents?</Trans>
|
||||
</h2>
|
||||
{canSignUp && (
|
||||
<div className={`flex max-w-xl flex-col items-center justify-center p-4 md:p-12`}>
|
||||
<h2 className="mt-8 text-center text-xl font-semibold md:mt-0">
|
||||
<Trans>Need to sign documents?</Trans>
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground/60 mt-4 max-w-[55ch] text-center leading-normal">
|
||||
<Trans>
|
||||
Create your account and start using state-of-the-art document signing.
|
||||
</Trans>
|
||||
</p>
|
||||
<p className="text-muted-foreground/60 mt-4 max-w-[55ch] text-center leading-normal">
|
||||
<Trans>Create your account and start using state-of-the-art document signing.</Trans>
|
||||
</p>
|
||||
|
||||
<ClaimAccount defaultName={recipientName} defaultEmail={recipient.email} />
|
||||
</div>
|
||||
)}
|
||||
<ClaimAccount defaultName={recipientName} defaultEmail={recipient.email} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoggedIn && (
|
||||
<Link href="/documents" className="text-documenso-700 hover:text-documenso-600">
|
||||
<Trans>Go Back Home</Trans>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
{isLoggedIn && (
|
||||
<Link href="/documents" className="text-documenso-700 hover:text-documenso-600 mt-36">
|
||||
<Trans>Go Back Home</Trans>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<PollUntilDocumentCompleted document={document} />
|
||||
|
||||
@@ -150,7 +150,7 @@ export const DateField = ({
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 text-sm duration-200">
|
||||
{localDateString}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { DateTime } from 'luxon';
|
||||
import { signOut } from 'next-auth/react';
|
||||
|
||||
import { RecipientRole } from '@documenso/prisma/client';
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Alert, AlertDescription } from '@documenso/ui/primitives/alert';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { DialogFooter } from '@documenso/ui/primitives/dialog';
|
||||
@@ -25,19 +25,22 @@ export const DocumentActionAuthAccount = ({
|
||||
}: DocumentActionAuthAccountProps) => {
|
||||
const { recipient } = useRequiredDocumentAuthContext();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [isSigningOut, setIsSigningOut] = useState(false);
|
||||
|
||||
const { mutateAsync: encryptSecondaryData } = trpc.crypto.encryptSecondaryData.useMutation();
|
||||
|
||||
const handleChangeAccount = async (email: string) => {
|
||||
try {
|
||||
setIsSigningOut(true);
|
||||
|
||||
await signOut({
|
||||
redirect: false,
|
||||
const encryptedEmail = await encryptSecondaryData({
|
||||
data: email,
|
||||
expiresAt: DateTime.now().plus({ days: 1 }).toMillis(),
|
||||
});
|
||||
|
||||
router.push(`/signin#email=${email}`);
|
||||
await signOut({
|
||||
callbackUrl: `/signin?email=${encodeURIComponent(encryptedEmail)}`,
|
||||
});
|
||||
} catch {
|
||||
setIsSigningOut(false);
|
||||
|
||||
|
||||
@@ -189,10 +189,7 @@ export const DropdownField = ({
|
||||
},
|
||||
)}
|
||||
>
|
||||
<SelectValue
|
||||
className="text-[clamp(0.625rem,1cqw,0.825rem)]"
|
||||
placeholder={`${_(msg`Select`)}`}
|
||||
/>
|
||||
<SelectValue placeholder={`${_(msg`Select`)}`} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="w-full ring-0 focus:ring-0" position="popper">
|
||||
{parsedFieldMeta?.values?.map((item, index) => (
|
||||
@@ -206,7 +203,7 @@ export const DropdownField = ({
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 flex items-center justify-center gap-x-1 duration-200">
|
||||
{field.customText}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -128,7 +128,7 @@ export const EmailField = ({ field, recipient, onSignField, onUnsignField }: Ema
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 truncate duration-200">
|
||||
{field.customText}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -29,16 +29,9 @@ export type SigningFormProps = {
|
||||
recipient: Recipient;
|
||||
fields: Field[];
|
||||
redirectUrl?: string | null;
|
||||
isRecipientsTurn: boolean;
|
||||
};
|
||||
|
||||
export const SigningForm = ({
|
||||
document,
|
||||
recipient,
|
||||
fields,
|
||||
redirectUrl,
|
||||
isRecipientsTurn,
|
||||
}: SigningFormProps) => {
|
||||
export const SigningForm = ({ document, recipient, fields, redirectUrl }: SigningFormProps) => {
|
||||
const router = useRouter();
|
||||
const analytics = useAnalytics();
|
||||
const { data: session } = useSession();
|
||||
@@ -157,7 +150,6 @@ export const SigningForm = ({
|
||||
fields={fields}
|
||||
fieldsValidated={fieldsValidated}
|
||||
role={recipient.role}
|
||||
disabled={!isRecipientsTurn}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -221,7 +213,6 @@ export const SigningForm = ({
|
||||
fields={fields}
|
||||
fieldsValidated={fieldsValidated}
|
||||
role={recipient.role}
|
||||
disabled={!isRecipientsTurn}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -131,7 +131,7 @@ export const InitialsField = ({
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 truncate duration-200">
|
||||
{field.customText}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -172,7 +172,7 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 truncate duration-200">
|
||||
{field.customText}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -259,7 +259,7 @@ export const NumberField = ({ field, recipient, onSignField, onUnsignField }: Nu
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
|
||||
<p className="text-muted-foreground dark:text-background/80 flex items-center justify-center gap-x-1 duration-200">
|
||||
{field.customText}
|
||||
</p>
|
||||
)}
|
||||
@@ -267,7 +267,7 @@ export const NumberField = ({ field, recipient, onSignField, onUnsignField }: Nu
|
||||
<Dialog open={showRadioModal} onOpenChange={setShowRadioModal}>
|
||||
<DialogContent>
|
||||
<DialogTitle>
|
||||
{parsedFieldMeta?.label ? parsedFieldMeta?.label : <Trans>Number</Trans>}
|
||||
{parsedFieldMeta?.label ? parsedFieldMeta?.label : <Trans>Add number</Trans>}
|
||||
</DialogTitle>
|
||||
|
||||
<div>
|
||||
|
||||
@@ -9,7 +9,6 @@ import { isRecipientAuthorized } from '@documenso/lib/server-only/document/is-re
|
||||
import { viewedDocument } from '@documenso/lib/server-only/document/viewed-document';
|
||||
import { getCompletedFieldsForToken } from '@documenso/lib/server-only/field/get-completed-fields-for-token';
|
||||
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
|
||||
import { getIsRecipientsTurnToSign } from '@documenso/lib/server-only/recipient/get-is-recipient-turn';
|
||||
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
||||
import { getRecipientSignatures } from '@documenso/lib/server-only/recipient/get-recipient-signatures';
|
||||
import { getUserByEmail } from '@documenso/lib/server-only/user/get-user-by-email';
|
||||
@@ -43,12 +42,6 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
|
||||
|
||||
const requestMetadata = extractNextHeaderRequestMetadata(requestHeaders);
|
||||
|
||||
const isRecipientsTurn = await getIsRecipientsTurnToSign({ token });
|
||||
|
||||
if (!isRecipientsTurn) {
|
||||
return redirect(`/sign/${token}/waiting`);
|
||||
}
|
||||
|
||||
const [document, fields, recipient, completedFields] = await Promise.all([
|
||||
getDocumentAndSenderByToken({
|
||||
token,
|
||||
@@ -153,7 +146,6 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
|
||||
document={document}
|
||||
fields={fields}
|
||||
completedFields={completedFields}
|
||||
isRecipientsTurn={isRecipientsTurn}
|
||||
/>
|
||||
</DocumentAuthProvider>
|
||||
</SigningProvider>
|
||||
|
||||
@@ -173,16 +173,16 @@ export const RadioField = ({ field, recipient, onSignField, onUnsignField }: Rad
|
||||
)}
|
||||
|
||||
{field.inserted && (
|
||||
<RadioGroup className="gap-y-1">
|
||||
<RadioGroup>
|
||||
{values?.map((item, index) => (
|
||||
<div key={index} className="flex items-center gap-x-1.5">
|
||||
<RadioGroupItem
|
||||
className="h-3 w-3"
|
||||
className=""
|
||||
value={item.value}
|
||||
id={`option-${index}`}
|
||||
checked={item.value === field.customText}
|
||||
/>
|
||||
<Label htmlFor={`option-${index}`} className="text-xs">
|
||||
<Label htmlFor={`option-${index}`}>
|
||||
{item.value.includes('empty-value-') ? '' : item.value}
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,6 @@ export type SignDialogProps = {
|
||||
fieldsValidated: () => void | Promise<void>;
|
||||
onSignatureComplete: () => void | Promise<void>;
|
||||
role: RecipientRole;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SignDialog = ({
|
||||
@@ -33,7 +32,6 @@ export const SignDialog = ({
|
||||
fieldsValidated,
|
||||
onSignatureComplete,
|
||||
role,
|
||||
disabled = false,
|
||||
}: SignDialogProps) => {
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
const truncatedTitle = truncateTitle(documentTitle);
|
||||
@@ -56,7 +54,6 @@ export const SignDialog = ({
|
||||
size="lg"
|
||||
onClick={fieldsValidated}
|
||||
loading={isSubmitting}
|
||||
disabled={disabled}
|
||||
>
|
||||
{isComplete ? <Trans>Complete</Trans> : <Trans>Next field</Trans>}
|
||||
</Button>
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { Trans, msg } from '@lingui/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { DateTime } from 'luxon';
|
||||
import { signOut } from 'next-auth/react';
|
||||
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
@@ -20,19 +20,24 @@ export const SigningAuthPageView = ({ email, emailHasAccount }: SigningAuthPageV
|
||||
const { _ } = useLingui();
|
||||
const { toast } = useToast();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [isSigningOut, setIsSigningOut] = useState(false);
|
||||
|
||||
const { mutateAsync: encryptSecondaryData } = trpc.crypto.encryptSecondaryData.useMutation();
|
||||
|
||||
const handleChangeAccount = async (email: string) => {
|
||||
try {
|
||||
setIsSigningOut(true);
|
||||
|
||||
await signOut({
|
||||
redirect: false,
|
||||
const encryptedEmail = await encryptSecondaryData({
|
||||
data: email,
|
||||
expiresAt: DateTime.now().plus({ days: 1 }).toMillis(),
|
||||
});
|
||||
|
||||
router.push(emailHasAccount ? `/signin#email=${email}` : `/signup#email=${email}`);
|
||||
await signOut({
|
||||
callbackUrl: emailHasAccount
|
||||
? `/signin?email=${encodeURIComponent(encryptedEmail)}`
|
||||
: `/signup?email=${encodeURIComponent(encryptedEmail)}`,
|
||||
});
|
||||
} catch {
|
||||
toast({
|
||||
title: _(msg`Something went wrong`),
|
||||
|
||||
@@ -128,7 +128,7 @@ export const SigningFieldContainer = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn('[container-type:size]', type === 'Checkbox' ? 'group' : '')}>
|
||||
<div className={cn(type === 'Checkbox' ? 'group' : '')}>
|
||||
<FieldRootContainer field={field}>
|
||||
{!field.inserted && !loading && !readOnlyField && (
|
||||
<button
|
||||
|
||||
@@ -39,7 +39,6 @@ export type SigningPageViewProps = {
|
||||
recipient: Recipient;
|
||||
fields: Field[];
|
||||
completedFields: CompletedField[];
|
||||
isRecipientsTurn: boolean;
|
||||
};
|
||||
|
||||
export const SigningPageView = ({
|
||||
@@ -47,7 +46,6 @@ export const SigningPageView = ({
|
||||
recipient,
|
||||
fields,
|
||||
completedFields,
|
||||
isRecipientsTurn,
|
||||
}: SigningPageViewProps) => {
|
||||
const { documentData, documentMeta } = document;
|
||||
|
||||
@@ -101,7 +99,6 @@ export const SigningPageView = ({
|
||||
recipient={recipient}
|
||||
fields={fields}
|
||||
redirectUrl={documentMeta?.redirectUrl}
|
||||
isRecipientsTurn={isRecipientsTurn}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -253,7 +253,7 @@ export const TextField = ({ field, recipient, onSignField, onUnsignField }: Text
|
||||
>
|
||||
<span className="flex items-center justify-center gap-x-1">
|
||||
<Type />
|
||||
{fieldDisplayName || <Trans>Text</Trans>}
|
||||
{fieldDisplayName || <Trans>Add text</Trans>}
|
||||
</span>
|
||||
</p>
|
||||
)}
|
||||
@@ -269,7 +269,7 @@ export const TextField = ({ field, recipient, onSignField, onUnsignField }: Text
|
||||
<Dialog open={showCustomTextModal} onOpenChange={setShowCustomTextModal}>
|
||||
<DialogContent>
|
||||
<DialogTitle>
|
||||
{parsedFieldMeta?.label ? parsedFieldMeta?.label : <Trans>Text</Trans>}
|
||||
{parsedFieldMeta?.label ? parsedFieldMeta?.label : <Trans>Add Text</Trans>}
|
||||
</DialogTitle>
|
||||
|
||||
<div>
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
import Link from 'next/link';
|
||||
import { notFound, redirect } from 'next/navigation';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
|
||||
import { getServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
|
||||
import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
|
||||
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
|
||||
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
|
||||
import type { Team } from '@documenso/prisma/client';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
||||
type WaitingForTurnToSignPageProps = {
|
||||
params: { token?: string };
|
||||
};
|
||||
|
||||
export default async function WaitingForTurnToSignPage({
|
||||
params: { token },
|
||||
}: WaitingForTurnToSignPageProps) {
|
||||
setupI18nSSR();
|
||||
|
||||
if (!token) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
const { user } = await getServerComponentSession();
|
||||
|
||||
const [document, recipient] = await Promise.all([
|
||||
getDocumentAndSenderByToken({ token }).catch(() => null),
|
||||
getRecipientByToken({ token }).catch(() => null),
|
||||
]);
|
||||
|
||||
if (!document || !recipient) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
if (document.status === DocumentStatus.COMPLETED) {
|
||||
return redirect(`/sign/${token}/complete`);
|
||||
}
|
||||
|
||||
let isOwnerOrTeamMember = false;
|
||||
|
||||
let team: Team | null = null;
|
||||
|
||||
if (user) {
|
||||
isOwnerOrTeamMember = await getDocumentById({
|
||||
id: document.id,
|
||||
userId: user.id,
|
||||
teamId: document.teamId ?? undefined,
|
||||
})
|
||||
.then((document) => !!document)
|
||||
.catch(() => false);
|
||||
|
||||
if (document.teamId) {
|
||||
team = await getTeamById({
|
||||
userId: user.id,
|
||||
teamId: document.teamId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
|
||||
<div className="w-full max-w-md text-center">
|
||||
<h2 className="tracking-tigh text-3xl font-bold">
|
||||
<Trans>Waiting for Your Turn</Trans>
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground mt-2 text-sm">
|
||||
<Trans>
|
||||
It's currently not your turn to sign. You will receive an email with instructions once
|
||||
it's your turn to sign the document.
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<p className="text-muted-foreground mt-4 text-sm">
|
||||
<Trans>Please check your email for updates.</Trans>
|
||||
</p>
|
||||
|
||||
<div className="mt-4">
|
||||
{isOwnerOrTeamMember ? (
|
||||
<Button variant="link" asChild>
|
||||
<Link href={`${formatDocumentsPath(team?.url)}/${document.id}`}>
|
||||
<Trans>Were you trying to edit this document instead?</Trans>
|
||||
</Link>
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="link" asChild>
|
||||
<Link href="/documents">Return Home</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { env } from 'next-runtime-env';
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
IS_OIDC_SSO_ENABLED,
|
||||
OIDC_PROVIDER_LABEL,
|
||||
} from '@documenso/lib/constants/auth';
|
||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||
|
||||
import { SignInForm } from '~/components/forms/signin';
|
||||
|
||||
@@ -17,11 +19,24 @@ export const metadata: Metadata = {
|
||||
title: 'Sign In',
|
||||
};
|
||||
|
||||
export default function SignInPage() {
|
||||
type SignInPageProps = {
|
||||
searchParams: {
|
||||
email?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export default function SignInPage({ searchParams }: SignInPageProps) {
|
||||
setupI18nSSR();
|
||||
|
||||
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
|
||||
|
||||
const rawEmail = typeof searchParams.email === 'string' ? searchParams.email : undefined;
|
||||
const email = rawEmail ? decryptSecondaryData(rawEmail) : null;
|
||||
|
||||
if (!email && rawEmail) {
|
||||
redirect('/signin');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-screen max-w-lg px-4">
|
||||
<div className="border-border dark:bg-background z-10 rounded-xl border bg-neutral-100 p-6">
|
||||
@@ -35,6 +50,7 @@ export default function SignInPage() {
|
||||
<hr className="-mx-6 my-4" />
|
||||
|
||||
<SignInForm
|
||||
initialEmail={email || undefined}
|
||||
isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED}
|
||||
isOIDCSSOEnabled={IS_OIDC_SSO_ENABLED}
|
||||
oidcProviderLabel={OIDC_PROVIDER_LABEL}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { env } from 'next-runtime-env';
|
||||
|
||||
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
|
||||
import { IS_GOOGLE_SSO_ENABLED, IS_OIDC_SSO_ENABLED } from '@documenso/lib/constants/auth';
|
||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||
|
||||
import { SignUpFormV2 } from '~/components/forms/v2/signup';
|
||||
|
||||
@@ -12,7 +13,13 @@ export const metadata: Metadata = {
|
||||
title: 'Sign Up',
|
||||
};
|
||||
|
||||
export default function SignUpPage() {
|
||||
type SignUpPageProps = {
|
||||
searchParams: {
|
||||
email?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export default function SignUpPage({ searchParams }: SignUpPageProps) {
|
||||
setupI18nSSR();
|
||||
|
||||
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
|
||||
@@ -21,9 +28,17 @@ export default function SignUpPage() {
|
||||
redirect('/signin');
|
||||
}
|
||||
|
||||
const rawEmail = typeof searchParams.email === 'string' ? searchParams.email : undefined;
|
||||
const email = rawEmail ? decryptSecondaryData(rawEmail) : null;
|
||||
|
||||
if (!email && rawEmail) {
|
||||
redirect('/signup');
|
||||
}
|
||||
|
||||
return (
|
||||
<SignUpFormV2
|
||||
className="w-screen max-w-screen-2xl px-4 md:px-16 lg:-my-16"
|
||||
initialEmail={email || undefined}
|
||||
isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED}
|
||||
isOIDCSSOEnabled={IS_OIDC_SSO_ENABLED}
|
||||
/>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
|
||||
import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounced-value';
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
|
||||
export const DocumentSearch = ({ initialValue = '' }: { initialValue?: string }) => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const [searchTerm, setSearchTerm] = useState(initialValue);
|
||||
const debouncedSearchTerm = useDebouncedValue(searchTerm, 500);
|
||||
|
||||
const handleSearch = useCallback(
|
||||
(term: string) => {
|
||||
const params = new URLSearchParams(searchParams?.toString() ?? '');
|
||||
if (term) {
|
||||
params.set('search', term);
|
||||
} else {
|
||||
params.delete('search');
|
||||
}
|
||||
router.push(`?${params.toString()}`);
|
||||
},
|
||||
[router, searchParams],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
handleSearch(searchTerm);
|
||||
}, [debouncedSearchTerm]);
|
||||
|
||||
return (
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="Search documents..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -335,23 +335,6 @@ export const DocumentHistorySheet = ({
|
||||
]}
|
||||
/>
|
||||
))
|
||||
.with(
|
||||
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_VISIBILITY_UPDATED },
|
||||
({ data }) => (
|
||||
<DocumentHistorySheetChanges
|
||||
values={[
|
||||
{
|
||||
key: 'Old',
|
||||
value: data.from,
|
||||
},
|
||||
{
|
||||
key: 'New',
|
||||
value: data.to,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
),
|
||||
)
|
||||
.exhaustive()}
|
||||
|
||||
{isUserDetailsVisible && (
|
||||
|
||||
@@ -89,7 +89,7 @@ export const DocumentReadOnlyFields = ({ documentMeta, fields }: DocumentReadOnl
|
||||
className="h-full w-full object-contain dark:invert"
|
||||
/>
|
||||
) : (
|
||||
<p className="font-signature text-muted-foreground text-lg duration-200 sm:text-xl md:text-2xl">
|
||||
<p className="font-signature text-muted-foreground text-lg duration-200 sm:text-xl md:text-2xl lg:text-3xl">
|
||||
{field.Signature?.typedSignature}
|
||||
</p>
|
||||
),
|
||||
@@ -122,7 +122,7 @@ export const DocumentReadOnlyFields = ({ documentMeta, fields }: DocumentReadOnl
|
||||
{field.Recipient.signingStatus === SigningStatus.NOT_SIGNED && (
|
||||
<p
|
||||
className={cn('text-muted-foreground text-lg duration-200', {
|
||||
'font-signature sm:text-xl md:text-2xl':
|
||||
'font-signature sm:text-xl md:text-2xl lg:text-3xl':
|
||||
field.type === FieldType.SIGNATURE ||
|
||||
field.type === FieldType.FREE_SIGNATURE,
|
||||
})}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
@@ -307,18 +307,6 @@ export const SignInForm = ({
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const hash = window.location.hash.slice(1);
|
||||
|
||||
const params = new URLSearchParams(hash);
|
||||
|
||||
const email = params.get('email');
|
||||
|
||||
if (email) {
|
||||
form.setValue('email', email);
|
||||
}
|
||||
}, [form]);
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
@@ -203,18 +203,6 @@ export const SignUpFormV2 = ({
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const hash = window.location.hash.slice(1);
|
||||
|
||||
const params = new URLSearchParams(hash);
|
||||
|
||||
const email = params.get('email');
|
||||
|
||||
if (email) {
|
||||
form.setValue('email', email);
|
||||
}
|
||||
}, [form]);
|
||||
|
||||
return (
|
||||
<div className={cn('flex justify-center gap-x-12', className)}>
|
||||
<div className="border-border relative hidden flex-1 overflow-hidden rounded-xl border xl:flex">
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
import { createContext, useContext } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import type { GetTeamResponse } from '@documenso/lib/server-only/team/get-team';
|
||||
import type { Team } from '@documenso/prisma/client';
|
||||
|
||||
interface TeamProviderProps {
|
||||
children: React.ReactNode;
|
||||
team: GetTeamResponse;
|
||||
team: Team;
|
||||
}
|
||||
|
||||
const TeamContext = createContext<GetTeamResponse | null>(null);
|
||||
const TeamContext = createContext<Team | null>(null);
|
||||
|
||||
export const useCurrentTeam = () => {
|
||||
const context = useContext(TeamContext);
|
||||
|
||||
230
package-lock.json
generated
230
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@documenso/root",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@documenso/root",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
@@ -80,7 +80,7 @@
|
||||
},
|
||||
"apps/marketing": {
|
||||
"name": "@documenso/marketing",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@documenso/assets": "*",
|
||||
@@ -103,7 +103,7 @@
|
||||
"micro": "^10.0.1",
|
||||
"next": "14.2.6",
|
||||
"next-auth": "4.24.5",
|
||||
"next-axiom": "^1.5.1",
|
||||
"next-axiom": "^1.1.1",
|
||||
"next-contentlayer": "^0.3.4",
|
||||
"next-plausible": "^3.10.1",
|
||||
"perfect-freehand": "^1.2.0",
|
||||
@@ -410,23 +410,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"apps/marketing/node_modules/next-axiom": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-1.5.1.tgz",
|
||||
"integrity": "sha512-sWxIzuJOex48ugMDlXWzvGvDGv5YHZ3w8gLZbUQ/Yml7oy5jcCItJNws9D0qmASirp2e5/BnvHxs44+9CO0GAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"use-deep-compare": "^1.2.1",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": ">=14.0",
|
||||
"react": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"apps/marketing/node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
@@ -441,7 +424,7 @@
|
||||
},
|
||||
"apps/web": {
|
||||
"name": "@documenso/web",
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@documenso/api": "*",
|
||||
@@ -466,7 +449,7 @@
|
||||
"micro": "^10.0.1",
|
||||
"next": "14.2.6",
|
||||
"next-auth": "4.24.5",
|
||||
"next-axiom": "^1.5.1",
|
||||
"next-axiom": "^1.1.1",
|
||||
"next-plausible": "^3.10.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"papaparse": "^5.4.1",
|
||||
@@ -482,7 +465,7 @@
|
||||
"react-icons": "^4.11.0",
|
||||
"react-rnd": "^10.4.1",
|
||||
"recharts": "^2.7.2",
|
||||
"remeda": "^2.12.1",
|
||||
"remeda": "^1.27.1",
|
||||
"sharp": "0.32.6",
|
||||
"ts-pattern": "^5.0.5",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
@@ -510,23 +493,6 @@
|
||||
"integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==",
|
||||
"dev": true
|
||||
},
|
||||
"apps/web/node_modules/next-axiom": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-1.5.1.tgz",
|
||||
"integrity": "sha512-sWxIzuJOex48ugMDlXWzvGvDGv5YHZ3w8gLZbUQ/Yml7oy5jcCItJNws9D0qmASirp2e5/BnvHxs44+9CO0GAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"use-deep-compare": "^1.2.1",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": ">=14.0",
|
||||
"react": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"apps/web/node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
@@ -3467,34 +3433,6 @@
|
||||
"react-dom": "^16 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/@hello-pangea/dnd": {
|
||||
"version": "16.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-16.6.0.tgz",
|
||||
"integrity": "sha512-vfZ4GydqbtUPXSLfAvKvXQ6xwRzIjUSjVU0Sx+70VOhc2xx6CdmJXJ8YhH70RpbTUGjxctslQTHul9sIOxCfFQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.1",
|
||||
"css-box-model": "^1.2.1",
|
||||
"memoize-one": "^6.0.0",
|
||||
"raf-schd": "^4.0.3",
|
||||
"react-redux": "^8.1.3",
|
||||
"redux": "^4.2.1",
|
||||
"use-memo-one": "^1.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.5 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@hello-pangea/dnd/node_modules/redux": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@hexagon/base64": {
|
||||
"version": "1.1.28",
|
||||
"resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
|
||||
@@ -11110,16 +11048,6 @@
|
||||
"@types/unist": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/hoist-non-react-statics": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
||||
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||
@@ -14735,15 +14663,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-box-model": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
|
||||
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tiny-invariant": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/css.escape": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
|
||||
@@ -19337,15 +19256,6 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||
@@ -22729,12 +22639,6 @@
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/meow": {
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz",
|
||||
@@ -24184,6 +24088,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-axiom": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-1.1.1.tgz",
|
||||
"integrity": "sha512-0r/TJ+/zetD+uDc7B+2E7WpC86hEtQ1U+DuWYrP/JNmUz+ZdPFbrZgzOSqaZ6TwYbXP56VVlPfYwq1YsKHTHYQ==",
|
||||
"dependencies": {
|
||||
"remeda": "^1.29.0",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": ">=13.4",
|
||||
"react": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/next-contentlayer": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/next-contentlayer/-/next-contentlayer-0.3.4.tgz",
|
||||
@@ -27766,12 +27686,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/raf-schd": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
|
||||
"integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/railroad-diagrams": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
|
||||
@@ -28609,51 +28523,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz",
|
||||
"integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw=="
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
|
||||
"integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@types/hoist-non-react-statics": "^3.3.1",
|
||||
"@types/use-sync-external-store": "^0.0.3",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"react-is": "^18.0.0",
|
||||
"use-sync-external-store": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8 || ^17.0 || ^18.0",
|
||||
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-native": ">=0.59",
|
||||
"redux": "^4 || ^5.0.0-beta.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native": {
|
||||
"optional": true
|
||||
},
|
||||
"redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux/node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
|
||||
@@ -30148,25 +30017,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/remeda": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/remeda/-/remeda-2.12.1.tgz",
|
||||
"integrity": "sha512-hKFAbxbQe8PMd4+CYO1DYCrCbcZsUSa7e21g7+4co91GBy7BD+Ub6JdaLy76yPOp7PCPTAXRz/9NXtZ9w15jbg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"type-fest": "^4.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/remeda/node_modules/type-fest": {
|
||||
"version": "4.26.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz",
|
||||
"integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==",
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
"version": "1.29.0",
|
||||
"resolved": "https://registry.npmjs.org/remeda/-/remeda-1.29.0.tgz",
|
||||
"integrity": "sha512-M3LQ14KtMdQ1879lj/kKji3zBk158s7Rwg963mEkTfQFMxnKrIEAMxJfo/+0sp/+uGgN/KMVU2MBA4LNjqf8YQ=="
|
||||
},
|
||||
"node_modules/remote-git-tags": {
|
||||
"version": "3.0.0",
|
||||
@@ -34229,27 +34082,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/use-deep-compare": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/use-deep-compare/-/use-deep-compare-1.3.0.tgz",
|
||||
"integrity": "sha512-94iG+dEdEP/Sl3WWde+w9StIunlV8Dgj+vkt5wTwMoFQLaijiEZSXXy8KtcStpmEDtIptRJiNeD4ACTtVvnIKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dequal": "2.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-memo-one": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz",
|
||||
"integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sidecar": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
||||
@@ -36797,7 +36629,7 @@
|
||||
"pg": "^8.11.3",
|
||||
"playwright": "1.43.0",
|
||||
"react": "^18",
|
||||
"remeda": "^2.12.1",
|
||||
"remeda": "^1.27.1",
|
||||
"sharp": "0.32.6",
|
||||
"stripe": "^12.7.0",
|
||||
"ts-pattern": "^5.0.5",
|
||||
@@ -36996,7 +36828,6 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@documenso/lib": "*",
|
||||
"@hello-pangea/dnd": "^16.6.0",
|
||||
"@hookform/resolvers": "^3.3.0",
|
||||
"@lingui/macro": "^4.11.3",
|
||||
"@lingui/react": "^4.11.3",
|
||||
@@ -37043,7 +36874,6 @@
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-pdf": "7.7.3",
|
||||
"react-rnd": "^10.4.1",
|
||||
"remeda": "^1.27.1",
|
||||
"tailwind-merge": "^1.12.0",
|
||||
"tailwindcss-animate": "^1.0.5",
|
||||
"ts-pattern": "^5.0.5",
|
||||
@@ -37096,12 +36926,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"packages/ui/node_modules/remeda": {
|
||||
"version": "1.61.0",
|
||||
"resolved": "https://registry.npmjs.org/remeda/-/remeda-1.61.0.tgz",
|
||||
"integrity": "sha512-caKfSz9rDeSKBQQnlJnVW3mbVdFgxgGWQKq1XlFokqjf+hQD5gxutLGTTY2A/x24UxVyJe9gH5fAkFI63ULw4A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"packages/ui/node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "1.7.2-rc.0",
|
||||
"version": "1.7.1-rc.0",
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"build:web": "turbo run build --filter=@documenso/web",
|
||||
|
||||
@@ -293,7 +293,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
timezone,
|
||||
dateFormat: dateFormat?.value,
|
||||
redirectUrl: body.meta.redirectUrl,
|
||||
signingOrder: body.meta.signingOrder,
|
||||
requestMetadata: extractNextApiRequestMetadata(args.req),
|
||||
});
|
||||
|
||||
@@ -302,9 +301,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
documentId: document.id,
|
||||
userId: user.id,
|
||||
teamId: team?.id,
|
||||
data: {
|
||||
...body.authOptions,
|
||||
},
|
||||
data: body.authOptions,
|
||||
requestMetadata: extractNextApiRequestMetadata(args.req),
|
||||
});
|
||||
}
|
||||
@@ -328,7 +325,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
email: recipient.email,
|
||||
token: recipient.token,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
|
||||
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
||||
})),
|
||||
@@ -500,7 +496,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
email: recipient.email,
|
||||
token: recipient.token,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
|
||||
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
||||
})),
|
||||
@@ -593,7 +588,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
email: recipient.email,
|
||||
token: recipient.token,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
|
||||
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
||||
})),
|
||||
@@ -719,7 +713,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
|
||||
createRecipient: authenticatedMiddleware(async (args, user, team) => {
|
||||
const { id: documentId } = args.params;
|
||||
const { name, email, role, authOptions, signingOrder } = args.body;
|
||||
const { name, email, role, authOptions } = args.body;
|
||||
|
||||
const document = await getDocumentById({
|
||||
id: Number(documentId),
|
||||
@@ -768,16 +762,11 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
userId: user.id,
|
||||
teamId: team?.id,
|
||||
recipients: [
|
||||
...recipients.map(({ email, name }) => ({
|
||||
email,
|
||||
name,
|
||||
role,
|
||||
})),
|
||||
...recipients,
|
||||
{
|
||||
email,
|
||||
name,
|
||||
role,
|
||||
signingOrder,
|
||||
actionAuth: authOptions?.actionAuth ?? null,
|
||||
},
|
||||
],
|
||||
@@ -810,7 +799,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
|
||||
updateRecipient: authenticatedMiddleware(async (args, user, team) => {
|
||||
const { id: documentId, recipientId } = args.params;
|
||||
const { name, email, role, authOptions, signingOrder } = args.body;
|
||||
const { name, email, role, authOptions } = args.body;
|
||||
|
||||
const document = await getDocumentById({
|
||||
id: Number(documentId),
|
||||
@@ -844,7 +833,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
|
||||
email,
|
||||
name,
|
||||
role,
|
||||
signingOrder,
|
||||
actionAuth: authOptions?.actionAuth,
|
||||
requestMetadata: extractNextApiRequestMetadata(args.req),
|
||||
}).catch(() => null);
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
import {
|
||||
DocumentDataType,
|
||||
DocumentSigningOrder,
|
||||
FieldType,
|
||||
ReadStatus,
|
||||
RecipientRole,
|
||||
@@ -104,7 +103,6 @@ export const ZCreateDocumentMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
}),
|
||||
),
|
||||
meta: z
|
||||
@@ -125,7 +123,6 @@ export const ZCreateDocumentMutationSchema = z.object({
|
||||
enum: DATE_FORMATS.map((format) => format.value),
|
||||
}),
|
||||
redirectUrl: z.string(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
})
|
||||
.partial(),
|
||||
authOptions: z
|
||||
@@ -150,7 +147,6 @@ export const ZCreateDocumentMutationResponseSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
||||
signingUrl: z.string(),
|
||||
}),
|
||||
@@ -169,7 +165,6 @@ export const ZCreateDocumentFromTemplateMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
}),
|
||||
),
|
||||
meta: z
|
||||
@@ -179,7 +174,6 @@ export const ZCreateDocumentFromTemplateMutationSchema = z.object({
|
||||
timezone: z.string(),
|
||||
dateFormat: z.string(),
|
||||
redirectUrl: z.string(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
})
|
||||
.partial()
|
||||
.optional(),
|
||||
@@ -206,7 +200,6 @@ export const ZCreateDocumentFromTemplateMutationResponseSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
||||
signingUrl: z.string(),
|
||||
}),
|
||||
@@ -226,7 +219,6 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
|
||||
id: z.number(),
|
||||
name: z.string().optional(),
|
||||
email: z.string().email().min(1),
|
||||
signingOrder: z.number().nullish(),
|
||||
}),
|
||||
)
|
||||
.refine(
|
||||
@@ -245,7 +237,6 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
|
||||
timezone: z.string(),
|
||||
dateFormat: z.string(),
|
||||
redirectUrl: ZUrlSchema,
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
})
|
||||
.partial()
|
||||
.optional(),
|
||||
@@ -272,7 +263,6 @@ export const ZGenerateDocumentFromTemplateMutationResponseSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
token: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
|
||||
signingUrl: z.string(),
|
||||
}),
|
||||
@@ -287,7 +277,6 @@ export const ZCreateRecipientMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().min(1),
|
||||
role: z.nativeEnum(RecipientRole).optional().default(RecipientRole.SIGNER),
|
||||
signingOrder: z.number().nullish(),
|
||||
authOptions: z
|
||||
.object({
|
||||
actionAuth: ZRecipientActionAuthTypesSchema.optional(),
|
||||
@@ -316,7 +305,6 @@ export const ZSuccessfulRecipientResponseSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
name: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().nullish(),
|
||||
token: z.string(),
|
||||
// !: Not used for now
|
||||
// expired: z.string(),
|
||||
@@ -434,7 +422,6 @@ export const ZTemplateMetaSchema = z.object({
|
||||
dateFormat: z.string().nullish(),
|
||||
templateId: z.number(),
|
||||
redirectUrl: z.string().nullish(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).nullish().default(DocumentSigningOrder.PARALLEL),
|
||||
});
|
||||
|
||||
export const ZTemplateSchema = z.object({
|
||||
@@ -456,7 +443,6 @@ export const ZRecipientSchema = z.object({
|
||||
email: z.string().email().min(1),
|
||||
name: z.string(),
|
||||
token: z.string(),
|
||||
signingOrder: z.number().nullish(),
|
||||
documentDeletedAt: z.date().nullish(),
|
||||
expired: z.date().nullish(),
|
||||
signedAt: z.date().nullish(),
|
||||
@@ -510,7 +496,6 @@ export const ZTemplateWithDataSchema = ZTemplateSchema.extend({
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
signingOrder: true,
|
||||
authOptions: true,
|
||||
role: true,
|
||||
}).array(),
|
||||
|
||||
@@ -41,10 +41,11 @@ test.describe('[EE_ONLY]', () => {
|
||||
// Add 2 signers.
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
await page.getByLabel('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByLabel('Name').nth(1).fill('Recipient 2');
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Email', exact: true })
|
||||
.fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Display advanced settings.
|
||||
await page.getByLabel('Show advanced settings').check();
|
||||
@@ -76,11 +77,9 @@ test('[DOCUMENT_FLOW]: add signers', async ({ page }) => {
|
||||
// Add 2 signers.
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByLabel('Name').nth(1).fill('Recipient 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Advanced settings should not be visible for non EE users.
|
||||
await expect(page.getByLabel('Show advanced settings')).toBeHidden();
|
||||
|
||||
@@ -4,13 +4,7 @@ import path from 'node:path';
|
||||
|
||||
import { getRecipientByEmail } from '@documenso/lib/server-only/recipient/get-recipient-by-email';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import {
|
||||
DocumentSigningOrder,
|
||||
DocumentStatus,
|
||||
FieldType,
|
||||
RecipientRole,
|
||||
SigningStatus,
|
||||
} from '@documenso/prisma/client';
|
||||
import { DocumentStatus, FieldType, RecipientRole } from '@documenso/prisma/client';
|
||||
import {
|
||||
seedBlankDocument,
|
||||
seedPendingDocumentWithFullFields,
|
||||
@@ -143,9 +137,8 @@ test('[DOCUMENT_FLOW]: should be able to create a document with multiple recipie
|
||||
await page.getByPlaceholder('Email').fill('user1@example.com');
|
||||
await page.getByPlaceholder('Name').fill('User 1');
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email').nth(1).fill('user2@example.com');
|
||||
await page.getByLabel('Name').nth(1).fill('User 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('user2@example.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('User 2');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
@@ -224,20 +217,20 @@ test('[DOCUMENT_FLOW]: should be able to create a document with multiple recipie
|
||||
await page.getByPlaceholder('Name').fill('User 1');
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email').nth(1).fill('user2@example.com');
|
||||
await page.getByLabel('Name').nth(1).fill('User 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('user2@example.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('User 2');
|
||||
await page.locator('button[role="combobox"]').nth(1).click();
|
||||
await page.getByLabel('Receives copy').click();
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email').nth(2).fill('user3@example.com');
|
||||
await page.getByLabel('Name').nth(2).fill('User 3');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).nth(1).fill('user3@example.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(2).fill('User 3');
|
||||
await page.locator('button[role="combobox"]').nth(2).click();
|
||||
await page.getByLabel('Needs to approve').click();
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email').nth(3).fill('user4@example.com');
|
||||
await page.getByLabel('Name').nth(3).fill('User 4');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).nth(2).fill('user4@example.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(3).fill('User 4');
|
||||
await page.locator('button[role="combobox"]').nth(3).click();
|
||||
await page.getByLabel('Needs to view').click();
|
||||
|
||||
@@ -510,163 +503,3 @@ test('[DOCUMENT_FLOW]: should be able to sign a document with custom date', asyn
|
||||
expect(completedStatus).toBe(DocumentStatus.COMPLETED);
|
||||
}).toPass();
|
||||
});
|
||||
|
||||
test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recipients in sequential order', async ({
|
||||
page,
|
||||
}) => {
|
||||
const user = await seedUser();
|
||||
const document = await seedBlankDocument(user);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/documents/${document.id}/edit`,
|
||||
});
|
||||
|
||||
const documentTitle = `Sequential-Signing-${Date.now()}.pdf`;
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
|
||||
await page.getByLabel('Title').fill(documentTitle);
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
|
||||
await page.getByLabel('Enable signing order').check();
|
||||
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
if (i > 1) {
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
}
|
||||
await page
|
||||
.getByPlaceholder('Email')
|
||||
.nth(i - 1)
|
||||
.fill(`user${i}@example.com`);
|
||||
await page
|
||||
.getByPlaceholder('Name')
|
||||
.nth(i - 1)
|
||||
.fill(`User ${i}`);
|
||||
}
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
|
||||
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
if (i > 1) {
|
||||
await page.getByText(`User ${i} (user${i}@example.com)`).click();
|
||||
}
|
||||
await page.getByRole('button', { name: 'Signature' }).click();
|
||||
await page.locator('canvas').click({
|
||||
position: {
|
||||
x: 100,
|
||||
y: 100 * i,
|
||||
},
|
||||
});
|
||||
await page.getByText(`User ${i} (user${i}@example.com)`).click();
|
||||
}
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Add Subject' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Send' }).click();
|
||||
|
||||
await page.waitForURL('/documents');
|
||||
|
||||
await expect(page.getByRole('link', { name: documentTitle })).toBeVisible();
|
||||
|
||||
const createdDocument = await prisma.document.findFirst({
|
||||
where: { title: documentTitle },
|
||||
include: { Recipient: true },
|
||||
});
|
||||
|
||||
expect(createdDocument).not.toBeNull();
|
||||
expect(createdDocument?.Recipient.length).toBe(3);
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const recipient = createdDocument?.Recipient.find(
|
||||
(r) => r.email === `user${i + 1}@example.com`,
|
||||
);
|
||||
expect(recipient).not.toBeNull();
|
||||
|
||||
const fields = await prisma.field.findMany({
|
||||
where: { recipientId: recipient?.id, documentId: createdDocument?.id },
|
||||
});
|
||||
const recipientField = fields[0];
|
||||
|
||||
if (i > 0) {
|
||||
const previousRecipient = await prisma.recipient.findFirst({
|
||||
where: { email: `user${i}@example.com`, documentId: createdDocument?.id },
|
||||
});
|
||||
|
||||
expect(previousRecipient?.signingStatus).toBe(SigningStatus.SIGNED);
|
||||
}
|
||||
|
||||
await page.goto(`/sign/${recipient?.token}`);
|
||||
await expect(page.getByRole('heading', { name: 'Sign Document' })).toBeVisible();
|
||||
|
||||
await page.locator(`#field-${recipientField.id}`).getByRole('button').click();
|
||||
|
||||
const canvas = page.locator('canvas#signature');
|
||||
const box = await canvas.boundingBox();
|
||||
if (box) {
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4);
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
await page.getByRole('button', { name: 'Sign', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Complete' }).click();
|
||||
await page.getByRole('button', { name: 'Sign' }).click();
|
||||
|
||||
await page.waitForURL(`/sign/${recipient?.token}/complete`);
|
||||
await expect(page.getByText('Document Signed')).toBeVisible();
|
||||
|
||||
const updatedRecipient = await prisma.recipient.findFirst({
|
||||
where: { id: recipient?.id },
|
||||
});
|
||||
|
||||
expect(updatedRecipient?.signingStatus).toBe(SigningStatus.SIGNED);
|
||||
}
|
||||
|
||||
// Wait for the document to be signed.
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
const finalDocument = await prisma.document.findFirst({
|
||||
where: { id: createdDocument?.id },
|
||||
});
|
||||
|
||||
expect(finalDocument?.status).toBe(DocumentStatus.COMPLETED);
|
||||
});
|
||||
|
||||
test('[DOCUMENT_FLOW]: should prevent out-of-order signing in sequential mode', async ({
|
||||
page,
|
||||
}) => {
|
||||
const user = await seedUser();
|
||||
|
||||
const { document, recipients } = await seedPendingDocumentWithFullFields({
|
||||
owner: user,
|
||||
recipients: ['user1@example.com', 'user2@example.com', 'user3@example.com'],
|
||||
fields: [FieldType.SIGNATURE],
|
||||
recipientsCreateOptions: [{ signingOrder: 1 }, { signingOrder: 2 }, { signingOrder: 3 }],
|
||||
updateDocumentOptions: {
|
||||
documentMeta: {
|
||||
create: {
|
||||
signingOrder: DocumentSigningOrder.SEQUENTIAL,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const pendingRecipient = recipients.find((r) => r.signingOrder === 2);
|
||||
|
||||
await page.goto(`/sign/${pendingRecipient?.token}`);
|
||||
|
||||
await expect(page).toHaveURL(`/sign/${pendingRecipient?.token}/waiting`);
|
||||
|
||||
const activeRecipient = recipients.find((r) => r.signingOrder === 1);
|
||||
|
||||
await page.goto(`/sign/${activeRecipient?.token}`);
|
||||
|
||||
await expect(page).not.toHaveURL(`/sign/${activeRecipient?.token}/waiting`);
|
||||
await expect(page.getByRole('heading', { name: 'Sign Document' })).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
|
||||
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
||||
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
|
||||
import { apiSignin, apiSignout } from '../fixtures/authentication';
|
||||
import { checkDocumentTabCount } from '../fixtures/documents';
|
||||
|
||||
test('[TEAMS]: search respects team document visibility', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
const adminUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
const managerUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.MANAGER });
|
||||
const memberUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.MEMBER });
|
||||
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Searchable Document for Everyone',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'MANAGER_AND_ABOVE',
|
||||
title: 'Searchable Document for Managers',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Searchable Document for Admins',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const testCases = [
|
||||
{ user: adminUser, visibleDocs: 3 },
|
||||
{ user: managerUser, visibleDocs: 2 },
|
||||
{ user: memberUser, visibleDocs: 1 },
|
||||
];
|
||||
|
||||
for (const { user, visibleDocs } of testCases) {
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Searchable');
|
||||
await page.waitForURL(/search=Searchable/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', visibleDocs);
|
||||
|
||||
await apiSignout({ page });
|
||||
}
|
||||
});
|
||||
|
||||
test('[TEAMS]: search does not reveal documents from other teams', async ({ page }) => {
|
||||
const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments();
|
||||
const { team: teamB } = await seedTeamDocuments();
|
||||
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: teamA.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: teamA.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Unique Team A Document',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: teamB.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: teamB.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Unique Team B Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: teamAMember.email,
|
||||
redirectPath: `/t/${teamA.url}/documents`,
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Unique');
|
||||
await page.waitForURL(/search=Unique/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', 1);
|
||||
await expect(page.getByRole('link', { name: 'Unique Team A Document' })).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: 'Unique Team B Document' })).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[PERSONAL]: search does not reveal team documents in personal account', async ({ page }) => {
|
||||
const { team, teamMember2 } = await seedTeamDocuments();
|
||||
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: teamMember2,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: null,
|
||||
title: 'Personal Unique Document',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Team Unique Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: teamMember2.email,
|
||||
redirectPath: '/documents',
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Unique');
|
||||
await page.waitForURL(/search=Unique/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', 1);
|
||||
await expect(page.getByRole('link', { name: 'Personal Unique Document' })).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: 'Team Unique Document' })).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: search respects recipient visibility regardless of team visibility', async ({
|
||||
page,
|
||||
}) => {
|
||||
const team = await seedTeam();
|
||||
const memberUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.MEMBER });
|
||||
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [memberUser],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Admin Document with Member Recipient',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: memberUser.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Admin Document');
|
||||
await page.waitForURL(/search=Admin(%20|\+|\s)Document/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', 1);
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Document with Member Recipient' }),
|
||||
).toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: search by recipient name respects visibility', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
const adminUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
const memberUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MEMBER,
|
||||
name: 'Team Member',
|
||||
});
|
||||
|
||||
const uniqueRecipient = await seedUser();
|
||||
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [uniqueRecipient],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Admin Document for Unique Recipient',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// Admin should see the document when searching by recipient name
|
||||
await apiSignin({
|
||||
page,
|
||||
email: adminUser.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Unique Recipient');
|
||||
await page.waitForURL(/search=Unique(%20|\+|\s)Recipient/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', 1);
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Document for Unique Recipient' }),
|
||||
).toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
|
||||
// Member should not see the document when searching by recipient name
|
||||
await apiSignin({
|
||||
page,
|
||||
email: memberUser.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
await page.getByPlaceholder('Search documents...').fill('Unique Recipient');
|
||||
await page.waitForURL(/search=Unique(%20|\+|\s)Recipient/);
|
||||
|
||||
await checkDocumentTabCount(page, 'All', 0);
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Document for Unique Recipient' }),
|
||||
).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
||||
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedTeamEmail } from '@documenso/prisma/seed/teams';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
|
||||
import { apiSignin, apiSignout } from '../fixtures/authentication';
|
||||
@@ -355,354 +355,3 @@ test('[TEAMS]: delete completed team document', async ({ page }) => {
|
||||
await apiSignout({ page });
|
||||
}
|
||||
});
|
||||
|
||||
test('[TEAMS]: check document visibility based on team member role', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
|
||||
// Seed users with different roles
|
||||
const adminUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.ADMIN,
|
||||
});
|
||||
|
||||
const managerUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MANAGER,
|
||||
});
|
||||
|
||||
const memberUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MEMBER,
|
||||
});
|
||||
|
||||
const outsideUser = await seedUser();
|
||||
|
||||
// Seed documents with different visibility levels
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Document Visible to Everyone',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'MANAGER_AND_ABOVE',
|
||||
title: 'Document Visible to Manager and Above',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Document Visible to Admin',
|
||||
},
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [outsideUser],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Document Visible to Admin with Recipient',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// Test cases for each role
|
||||
const testCases = [
|
||||
{
|
||||
user: adminUser,
|
||||
expectedDocuments: [
|
||||
'Document Visible to Everyone',
|
||||
'Document Visible to Manager and Above',
|
||||
'Document Visible to Admin',
|
||||
'Document Visible to Admin with Recipient',
|
||||
],
|
||||
},
|
||||
{
|
||||
user: managerUser,
|
||||
expectedDocuments: ['Document Visible to Everyone', 'Document Visible to Manager and Above'],
|
||||
},
|
||||
{
|
||||
user: memberUser,
|
||||
expectedDocuments: ['Document Visible to Everyone'],
|
||||
},
|
||||
{
|
||||
user: outsideUser,
|
||||
expectedDocuments: ['Document Visible to Admin with Recipient'],
|
||||
},
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
await apiSignin({
|
||||
page,
|
||||
email: testCase.user.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Check that the user sees the expected documents
|
||||
for (const documentTitle of testCase.expectedDocuments) {
|
||||
await expect(page.getByRole('link', { name: documentTitle, exact: true })).toBeVisible();
|
||||
}
|
||||
|
||||
await apiSignout({ page });
|
||||
}
|
||||
});
|
||||
|
||||
test('[TEAMS]: ensure recipient can see document regardless of visibility', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
|
||||
// Seed a member user
|
||||
const memberUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MEMBER,
|
||||
});
|
||||
|
||||
// Seed a document with ADMIN visibility but make the member user a recipient
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [memberUser],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Admin Document with Member Recipient',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: memberUser.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Check that the member user can see the document
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Document with Member Recipient', exact: true }),
|
||||
).toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: check that members cannot see ADMIN-only documents', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
|
||||
// Seed a member user
|
||||
const memberUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MEMBER,
|
||||
});
|
||||
|
||||
// Seed an ADMIN-only document
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Admin Only Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: memberUser.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Check that the member user cannot see the ADMIN-only document
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Only Document', exact: true }),
|
||||
).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: check that managers cannot see ADMIN-only documents', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
|
||||
// Seed a manager user
|
||||
const managerUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.MANAGER,
|
||||
});
|
||||
|
||||
// Seed an ADMIN-only document
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'ADMIN',
|
||||
title: 'Admin Only Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: managerUser.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Check that the manager user cannot see the ADMIN-only document
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Admin Only Document', exact: true }),
|
||||
).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: check that admin can see MANAGER_AND_ABOVE documents', async ({ page }) => {
|
||||
const team = await seedTeam();
|
||||
|
||||
// Seed an admin user
|
||||
const adminUser = await seedTeamMember({
|
||||
teamId: team.id,
|
||||
role: TeamMemberRole.ADMIN,
|
||||
});
|
||||
|
||||
// Seed a MANAGER_AND_ABOVE document
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: team.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'MANAGER_AND_ABOVE',
|
||||
title: 'Manager and Above Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: adminUser.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Check that the admin user can see the MANAGER_AND_ABOVE document
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Manager and Above Document', exact: true }),
|
||||
).toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: users cannot see documents from other teams', async ({ page }) => {
|
||||
// Seed two teams with documents
|
||||
const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments();
|
||||
const { team: teamB, teamMember2: teamBMember } = await seedTeamDocuments();
|
||||
|
||||
// Seed a document in team B
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: teamB.owner,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: teamB.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Team B Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// Sign in as a member of team A
|
||||
await apiSignin({
|
||||
page,
|
||||
email: teamAMember.email,
|
||||
redirectPath: `/t/${teamA.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Verify that the user cannot see the document from team B
|
||||
await expect(page.getByRole('link', { name: 'Team B Document', exact: true })).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[TEAMS]: personal documents are not visible in team context', async ({ page }) => {
|
||||
// Seed a team and a user with personal documents
|
||||
const { team, teamMember2 } = await seedTeamDocuments();
|
||||
const personalUser = await seedUser();
|
||||
|
||||
// Seed a personal document for teamMember2
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: teamMember2,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: null, // Indicates a personal document
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Personal Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// Sign in as teamMember2 in the team context
|
||||
await apiSignin({
|
||||
page,
|
||||
email: teamMember2.email,
|
||||
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Verify that the personal document is not visible in the team context
|
||||
await expect(
|
||||
page.getByRole('link', { name: 'Personal Document', exact: true }),
|
||||
).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
test('[PERSONAL]: team documents are not visible in personal account', async ({ page }) => {
|
||||
// Seed a team and a user with personal documents
|
||||
const { team, teamMember2 } = await seedTeamDocuments();
|
||||
|
||||
// Seed a team document
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: teamMember2,
|
||||
recipients: [],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions: {
|
||||
teamId: team.id,
|
||||
visibility: 'EVERYONE',
|
||||
title: 'Team Document',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// Sign in as teamMember2 in the personal context
|
||||
await apiSignin({
|
||||
page,
|
||||
email: teamMember2.email,
|
||||
redirectPath: `/documents?status=COMPLETED`,
|
||||
});
|
||||
|
||||
// Verify that the team document is not visible in the personal context
|
||||
await expect(page.getByRole('link', { name: 'Team Document', exact: true })).not.toBeVisible();
|
||||
|
||||
await apiSignout({ page });
|
||||
});
|
||||
|
||||
@@ -42,8 +42,10 @@ test.describe('[EE_ONLY]', () => {
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
await page.getByRole('button', { name: 'Add Placeholder Recipient' }).click();
|
||||
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Email', exact: true })
|
||||
.fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Display advanced settings.
|
||||
await page.getByLabel('Show advanced settings').check();
|
||||
@@ -92,8 +94,8 @@ test('[TEMPLATE_FLOW]: add placeholder', async ({ page }) => {
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
await page.getByRole('button', { name: 'Add Placeholder Recipient' }).click();
|
||||
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Advanced settings should not be visible for non EE users.
|
||||
await expect(page.getByLabel('Show advanced settings')).toBeHidden();
|
||||
|
||||
@@ -76,8 +76,8 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
await page.getByRole('button', { name: 'Add Placeholder Recipient' }).click();
|
||||
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Apply require passkey for Recipient 1.
|
||||
if (isBillingEnabled) {
|
||||
@@ -211,8 +211,8 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
|
||||
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Recipient 1');
|
||||
await page.getByRole('button', { name: 'Add Placeholder Recipient' }).click();
|
||||
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
|
||||
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('recipient2@documenso.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).nth(1).fill('Recipient 2');
|
||||
|
||||
// Apply require passkey for Recipient 1.
|
||||
if (isBillingEnabled) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { isDeepEqual } from 'remeda';
|
||||
import { equals } from 'remeda';
|
||||
|
||||
import { getLimits } from '../client';
|
||||
import { FREE_PLAN_LIMITS } from '../constants';
|
||||
@@ -42,7 +42,7 @@ export const LimitsProvider = ({
|
||||
const newLimits = await getLimits({ teamId });
|
||||
|
||||
setLimits((oldLimits) => {
|
||||
if (isDeepEqual(oldLimits, newLimits)) {
|
||||
if (equals(oldLimits, newLimits)) {
|
||||
return oldLimits;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
import config from '@documenso/tailwind-config';
|
||||
|
||||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Hr,
|
||||
Html,
|
||||
Img,
|
||||
Preview,
|
||||
Section,
|
||||
Tailwind,
|
||||
Text,
|
||||
} from '../components';
|
||||
import type { TemplateDocumentCancelProps } from '../template-components/template-document-cancel';
|
||||
import TemplateDocumentImage from '../template-components/template-document-image';
|
||||
import { TemplateFooter } from '../template-components/template-footer';
|
||||
|
||||
export type DocumentCancelEmailTemplateProps = Partial<TemplateDocumentCancelProps>;
|
||||
|
||||
export const RecipientRemovedFromDocumentTemplate = ({
|
||||
inviterName = 'Lucas Smith',
|
||||
documentName = 'Open Source Pledge.pdf',
|
||||
assetBaseUrl = 'http://localhost:3002',
|
||||
}: DocumentCancelEmailTemplateProps) => {
|
||||
const previewText = `${inviterName} has removed you from the document ${documentName}.`;
|
||||
|
||||
const getAssetUrl = (path: string) => {
|
||||
return new URL(path, assetBaseUrl).toString();
|
||||
};
|
||||
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: config.theme.extend.colors,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Body className="mx-auto my-auto bg-white font-sans">
|
||||
<Section>
|
||||
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-4 backdrop-blur-sm">
|
||||
<Section>
|
||||
<Img
|
||||
src={getAssetUrl('/static/logo.png')}
|
||||
alt="Documenso Logo"
|
||||
className="mb-4 h-6"
|
||||
/>
|
||||
|
||||
<TemplateDocumentImage className="mt-6" assetBaseUrl={assetBaseUrl} />
|
||||
|
||||
<Section>
|
||||
<Text className="text-primary mx-auto mb-0 max-w-[80%] text-center text-lg font-semibold">
|
||||
{inviterName} has removed you from the document
|
||||
<br />"{documentName}"
|
||||
</Text>
|
||||
</Section>
|
||||
</Section>
|
||||
</Container>
|
||||
|
||||
<Hr className="mx-auto mt-12 max-w-xl" />
|
||||
|
||||
<Container className="mx-auto max-w-xl">
|
||||
<TemplateFooter />
|
||||
</Container>
|
||||
</Section>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
);
|
||||
};
|
||||
|
||||
export default RecipientRemovedFromDocumentTemplate;
|
||||
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { getBoundingClientRect } from '@documenso/lib/client-only/get-bounding-client-rect';
|
||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||
import type { Field } from '@documenso/prisma/client';
|
||||
import { Field } from '@documenso/prisma/client';
|
||||
|
||||
export const useFieldPageCoords = (field: Field) => {
|
||||
const [coords, setCoords] = useState({
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
||||
|
||||
import type { TDocumentVisibility } from '../types/document-visibility';
|
||||
|
||||
type DocumentVisibilityTypeData = {
|
||||
key: TDocumentVisibility;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export const DOCUMENT_VISIBILITY: Record<string, DocumentVisibilityTypeData> = {
|
||||
[DocumentVisibility.ADMIN]: {
|
||||
key: DocumentVisibility.ADMIN,
|
||||
value: 'Admins only',
|
||||
},
|
||||
[DocumentVisibility.EVERYONE]: {
|
||||
key: DocumentVisibility.EVERYONE,
|
||||
value: 'Everyone',
|
||||
},
|
||||
[DocumentVisibility.MANAGER_AND_ABOVE]: {
|
||||
key: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||
value: 'Managers and above',
|
||||
},
|
||||
} satisfies Record<TDocumentVisibility, DocumentVisibilityTypeData>;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const SUPPORTED_LANGUAGE_CODES = ['de', 'en', 'fr'] as const;
|
||||
export const SUPPORTED_LANGUAGE_CODES = ['de', 'en'] as const;
|
||||
|
||||
export const ZSupportedLanguageCodeSchema = z.enum(SUPPORTED_LANGUAGE_CODES).catch('en');
|
||||
|
||||
@@ -38,8 +38,4 @@ export const SUPPORTED_LANGUAGES: Record<string, SupportedLanguage> = {
|
||||
full: 'English',
|
||||
short: 'en',
|
||||
},
|
||||
fr: {
|
||||
full: 'French',
|
||||
short: 'fr',
|
||||
},
|
||||
} satisfies Record<SupportedLanguageCodes, SupportedLanguage>;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"pg": "^8.11.3",
|
||||
"playwright": "1.43.0",
|
||||
"react": "^18",
|
||||
"remeda": "^2.12.1",
|
||||
"remeda": "^1.27.1",
|
||||
"sharp": "0.32.6",
|
||||
"stripe": "^12.7.0",
|
||||
"ts-pattern": "^5.0.5",
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
diffDocumentMetaChanges,
|
||||
} from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { DocumentSigningOrder } from '@documenso/prisma/client';
|
||||
|
||||
export type CreateDocumentMetaOptions = {
|
||||
documentId: number;
|
||||
@@ -17,7 +16,6 @@ export type CreateDocumentMetaOptions = {
|
||||
password?: string;
|
||||
dateFormat?: string;
|
||||
redirectUrl?: string;
|
||||
signingOrder?: DocumentSigningOrder;
|
||||
userId: number;
|
||||
requestMetadata: RequestMetadata;
|
||||
};
|
||||
@@ -31,7 +29,6 @@ export const upsertDocumentMeta = async ({
|
||||
password,
|
||||
userId,
|
||||
redirectUrl,
|
||||
signingOrder,
|
||||
requestMetadata,
|
||||
}: CreateDocumentMetaOptions) => {
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
@@ -81,7 +78,6 @@ export const upsertDocumentMeta = async ({
|
||||
timezone,
|
||||
documentId,
|
||||
redirectUrl,
|
||||
signingOrder,
|
||||
},
|
||||
update: {
|
||||
subject,
|
||||
@@ -90,7 +86,6 @@ export const upsertDocumentMeta = async ({
|
||||
dateFormat,
|
||||
timezone,
|
||||
redirectUrl,
|
||||
signingOrder,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -2,18 +2,11 @@ import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-log
|
||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import {
|
||||
DocumentSigningOrder,
|
||||
DocumentStatus,
|
||||
RecipientRole,
|
||||
SendStatus,
|
||||
SigningStatus,
|
||||
} from '@documenso/prisma/client';
|
||||
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||
|
||||
import { jobs } from '../../jobs/client';
|
||||
import type { TRecipientActionAuth } from '../../types/document-auth';
|
||||
import { getIsRecipientsTurnToSign } from '../recipient/get-is-recipient-turn';
|
||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||
import { sendPendingEmail } from './send-pending-email';
|
||||
|
||||
@@ -36,7 +29,6 @@ const getDocument = async ({ token, documentId }: CompleteDocumentWithTokenOptio
|
||||
},
|
||||
},
|
||||
include: {
|
||||
documentMeta: true,
|
||||
Recipient: {
|
||||
where: {
|
||||
token,
|
||||
@@ -67,16 +59,6 @@ export const completeDocumentWithToken = async ({
|
||||
throw new Error(`Recipient ${recipient.id} has already signed`);
|
||||
}
|
||||
|
||||
if (document.documentMeta?.signingOrder === DocumentSigningOrder.SEQUENTIAL) {
|
||||
const isRecipientsTurn = await getIsRecipientsTurnToSign({ token: recipient.token });
|
||||
|
||||
if (!isRecipientsTurn) {
|
||||
throw new Error(
|
||||
`Recipient ${recipient.id} attempted to complete the document before it was their turn`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const fields = await prisma.field.findMany({
|
||||
where: {
|
||||
documentId: document.id,
|
||||
@@ -138,48 +120,17 @@ export const completeDocumentWithToken = async ({
|
||||
});
|
||||
});
|
||||
|
||||
const pendingRecipients = await prisma.recipient.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
signingOrder: true,
|
||||
},
|
||||
const pendingRecipients = await prisma.recipient.count({
|
||||
where: {
|
||||
documentId: document.id,
|
||||
signingStatus: {
|
||||
not: SigningStatus.SIGNED,
|
||||
},
|
||||
role: {
|
||||
not: RecipientRole.CC,
|
||||
},
|
||||
},
|
||||
// Composite sort so our next recipient is always the one with the lowest signing order or id
|
||||
// if there is a tie.
|
||||
orderBy: [{ signingOrder: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],
|
||||
});
|
||||
|
||||
if (pendingRecipients.length > 0) {
|
||||
if (pendingRecipients > 0) {
|
||||
await sendPendingEmail({ documentId, recipientId: recipient.id });
|
||||
|
||||
if (document.documentMeta?.signingOrder === DocumentSigningOrder.SEQUENTIAL) {
|
||||
const [nextRecipient] = pendingRecipients;
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.recipient.update({
|
||||
where: { id: nextRecipient.id },
|
||||
data: { sendStatus: SendStatus.SENT },
|
||||
});
|
||||
|
||||
await jobs.triggerJob({
|
||||
name: 'send.signing.requested.email',
|
||||
payload: {
|
||||
userId: document.userId,
|
||||
documentId: document.id,
|
||||
recipientId: nextRecipient.id,
|
||||
requestMetadata,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const haveAllRecipientsSigned = await prisma.document.findFirst({
|
||||
@@ -187,7 +138,7 @@ export const completeDocumentWithToken = async ({
|
||||
id: document.id,
|
||||
Recipient: {
|
||||
every: {
|
||||
OR: [{ signingStatus: SigningStatus.SIGNED }, { role: RecipientRole.CC }],
|
||||
signingStatus: SigningStatus.SIGNED,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,11 +2,10 @@ import { DateTime } from 'luxon';
|
||||
import { P, match } from 'ts-pattern';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
|
||||
import { RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
||||
import type { Document, Prisma, Team, TeamEmail, User } from '@documenso/prisma/client';
|
||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||
|
||||
import { DocumentVisibility } from '../../types/document-visibility';
|
||||
import type { FindResultSet } from '../../types/find-result-set';
|
||||
import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document';
|
||||
|
||||
@@ -25,7 +24,6 @@ export type FindDocumentsOptions = {
|
||||
};
|
||||
period?: PeriodSelectorValue;
|
||||
senderIds?: number[];
|
||||
search?: string;
|
||||
};
|
||||
|
||||
export const findDocuments = async ({
|
||||
@@ -38,7 +36,6 @@ export const findDocuments = async ({
|
||||
orderBy,
|
||||
period,
|
||||
senderIds,
|
||||
search,
|
||||
}: FindDocumentsOptions) => {
|
||||
const { user, team } = await prisma.$transaction(async (tx) => {
|
||||
const user = await tx.user.findFirstOrThrow({
|
||||
@@ -61,14 +58,6 @@ export const findDocuments = async ({
|
||||
},
|
||||
include: {
|
||||
teamEmail: true,
|
||||
members: {
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
select: {
|
||||
role: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -81,7 +70,6 @@ export const findDocuments = async ({
|
||||
|
||||
const orderByColumn = orderBy?.column ?? 'createdAt';
|
||||
const orderByDirection = orderBy?.direction ?? 'desc';
|
||||
const teamMemberRole = team?.members[0].role ?? null;
|
||||
|
||||
const termFilters = match(term)
|
||||
.with(P.string.minLength(1), () => {
|
||||
@@ -94,45 +82,7 @@ export const findDocuments = async ({
|
||||
})
|
||||
.otherwise(() => undefined);
|
||||
|
||||
const searchFilter: Prisma.DocumentWhereInput = {
|
||||
OR: [
|
||||
{ title: { contains: search, mode: 'insensitive' } },
|
||||
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
|
||||
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
|
||||
],
|
||||
};
|
||||
|
||||
const visibilityFilters = [
|
||||
match(teamMemberRole)
|
||||
.with(TeamMemberRole.ADMIN, () => ({
|
||||
visibility: {
|
||||
in: [
|
||||
DocumentVisibility.EVERYONE,
|
||||
DocumentVisibility.MANAGER_AND_ABOVE,
|
||||
DocumentVisibility.ADMIN,
|
||||
],
|
||||
},
|
||||
}))
|
||||
.with(TeamMemberRole.MANAGER, () => ({
|
||||
visibility: {
|
||||
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
|
||||
},
|
||||
}))
|
||||
.otherwise(() => ({ visibility: DocumentVisibility.EVERYONE })),
|
||||
{
|
||||
Recipient: {
|
||||
some: {
|
||||
email: user.email,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
let filters: Prisma.DocumentWhereInput | null = findDocumentsFilter(status, user);
|
||||
|
||||
if (team) {
|
||||
filters = findTeamDocumentsFilter(status, team, visibilityFilters);
|
||||
}
|
||||
const filters = team ? findTeamDocumentsFilter(status, team) : findDocumentsFilter(status, user);
|
||||
|
||||
if (filters === null) {
|
||||
return {
|
||||
@@ -198,7 +148,9 @@ export const findDocuments = async ({
|
||||
}
|
||||
|
||||
const whereClause: Prisma.DocumentWhereInput = {
|
||||
AND: [{ ...termFilters }, { ...filters }, { ...deletedFilter }, { ...searchFilter }],
|
||||
...termFilters,
|
||||
...filters,
|
||||
...deletedFilter,
|
||||
};
|
||||
|
||||
if (period) {
|
||||
@@ -381,7 +333,6 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
|
||||
const findTeamDocumentsFilter = (
|
||||
status: ExtendedDocumentStatus,
|
||||
team: Team & { teamEmail: TeamEmail | null },
|
||||
visibilityFilters: Prisma.DocumentWhereInput[],
|
||||
) => {
|
||||
const teamEmail = team.teamEmail?.email ?? null;
|
||||
|
||||
@@ -392,7 +343,6 @@ const findTeamDocumentsFilter = (
|
||||
OR: [
|
||||
{
|
||||
teamId: team.id,
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -408,7 +358,6 @@ const findTeamDocumentsFilter = (
|
||||
email: teamEmail,
|
||||
},
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
});
|
||||
|
||||
// Filter to display all documents that have been sent by the team email.
|
||||
@@ -416,7 +365,6 @@ const findTeamDocumentsFilter = (
|
||||
User: {
|
||||
email: teamEmail,
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -441,7 +389,6 @@ const findTeamDocumentsFilter = (
|
||||
},
|
||||
},
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
};
|
||||
})
|
||||
.with(ExtendedDocumentStatus.DRAFT, () => {
|
||||
@@ -450,7 +397,6 @@ const findTeamDocumentsFilter = (
|
||||
{
|
||||
teamId: team.id,
|
||||
status: ExtendedDocumentStatus.DRAFT,
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -461,7 +407,6 @@ const findTeamDocumentsFilter = (
|
||||
User: {
|
||||
email: teamEmail,
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -473,7 +418,6 @@ const findTeamDocumentsFilter = (
|
||||
{
|
||||
teamId: team.id,
|
||||
status: ExtendedDocumentStatus.PENDING,
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -492,13 +436,11 @@ const findTeamDocumentsFilter = (
|
||||
},
|
||||
},
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
{
|
||||
User: {
|
||||
email: teamEmail,
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -512,7 +454,6 @@ const findTeamDocumentsFilter = (
|
||||
OR: [
|
||||
{
|
||||
teamId: team.id,
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -525,13 +466,11 @@ const findTeamDocumentsFilter = (
|
||||
email: teamEmail,
|
||||
},
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
{
|
||||
User: {
|
||||
email: teamEmail,
|
||||
},
|
||||
OR: visibilityFilters,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Prisma } from '@documenso/prisma/client';
|
||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||
|
||||
import { DocumentVisibility } from '../../types/document-visibility';
|
||||
import { getTeamById } from '../team/get-team';
|
||||
|
||||
export type GetDocumentByIdOptions = {
|
||||
@@ -32,11 +28,6 @@ export const getDocumentById = async ({ id, userId, teamId }: GetDocumentByIdOpt
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
Recipient: {
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
team: {
|
||||
select: {
|
||||
id: true,
|
||||
@@ -124,35 +115,5 @@ export const getDocumentWhereInput = async ({
|
||||
);
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
});
|
||||
|
||||
const visibilityFilters = [
|
||||
...match(team.currentTeamMember?.role)
|
||||
.with(TeamMemberRole.ADMIN, () => [
|
||||
{ visibility: DocumentVisibility.EVERYONE },
|
||||
{ visibility: DocumentVisibility.MANAGER_AND_ABOVE },
|
||||
{ visibility: DocumentVisibility.ADMIN },
|
||||
])
|
||||
.with(TeamMemberRole.MANAGER, () => [
|
||||
{ visibility: DocumentVisibility.EVERYONE },
|
||||
{ visibility: DocumentVisibility.MANAGER_AND_ABOVE },
|
||||
])
|
||||
.otherwise(() => [{ visibility: DocumentVisibility.EVERYONE }]),
|
||||
{
|
||||
Recipient: {
|
||||
some: {
|
||||
email: user.email,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
...documentWhereInput,
|
||||
OR: [...visibilityFilters],
|
||||
};
|
||||
return documentWhereInput;
|
||||
};
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
import { DateTime } from 'luxon';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { TeamMemberRole } from '@documenso/prisma/client';
|
||||
import type { Prisma, User } from '@documenso/prisma/client';
|
||||
import { SigningStatus } from '@documenso/prisma/client';
|
||||
import { isExtendedDocumentStatus } from '@documenso/prisma/guards/is-extended-document-status';
|
||||
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
|
||||
|
||||
import { DocumentVisibility } from '../../types/document-visibility';
|
||||
|
||||
export type GetStatsInput = {
|
||||
user: User;
|
||||
team?: Omit<GetTeamCountsOption, 'createdAt'>;
|
||||
period?: PeriodSelectorValue;
|
||||
search?: string;
|
||||
};
|
||||
|
||||
export const getStats = async ({ user, period, search, ...options }: GetStatsInput) => {
|
||||
export const getStats = async ({ user, period, ...options }: GetStatsInput) => {
|
||||
let createdAt: Prisma.DocumentWhereInput['createdAt'];
|
||||
|
||||
if (period) {
|
||||
@@ -32,14 +27,8 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
|
||||
}
|
||||
|
||||
const [ownerCounts, notSignedCounts, hasSignedCounts] = await (options.team
|
||||
? getTeamCounts({
|
||||
...options.team,
|
||||
createdAt,
|
||||
currentUserEmail: user.email,
|
||||
userId: user.id,
|
||||
search,
|
||||
})
|
||||
: getCounts({ user, createdAt, search }));
|
||||
? getTeamCounts({ ...options.team, createdAt })
|
||||
: getCounts({ user, createdAt }));
|
||||
|
||||
const stats: Record<ExtendedDocumentStatus, number> = {
|
||||
[ExtendedDocumentStatus.DRAFT]: 0,
|
||||
@@ -79,18 +68,9 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
|
||||
type GetCountsOption = {
|
||||
user: User;
|
||||
createdAt: Prisma.DocumentWhereInput['createdAt'];
|
||||
search?: string;
|
||||
};
|
||||
|
||||
const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
||||
const searchFilter: Prisma.DocumentWhereInput = {
|
||||
OR: [
|
||||
{ title: { contains: search, mode: 'insensitive' } },
|
||||
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
|
||||
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
|
||||
],
|
||||
};
|
||||
|
||||
const getCounts = async ({ user, createdAt }: GetCountsOption) => {
|
||||
return Promise.all([
|
||||
// Owner counts.
|
||||
prisma.document.groupBy({
|
||||
@@ -103,7 +83,6 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
||||
createdAt,
|
||||
teamId: null,
|
||||
deletedAt: null,
|
||||
AND: [searchFilter],
|
||||
},
|
||||
}),
|
||||
// Not signed counts.
|
||||
@@ -122,7 +101,6 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
||||
},
|
||||
},
|
||||
createdAt,
|
||||
AND: [searchFilter],
|
||||
},
|
||||
}),
|
||||
// Has signed counts.
|
||||
@@ -160,7 +138,6 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
|
||||
},
|
||||
},
|
||||
],
|
||||
AND: [searchFilter],
|
||||
},
|
||||
}),
|
||||
]);
|
||||
@@ -170,11 +147,7 @@ type GetTeamCountsOption = {
|
||||
teamId: number;
|
||||
teamEmail?: string;
|
||||
senderIds?: number[];
|
||||
currentUserEmail: string;
|
||||
userId: number;
|
||||
createdAt: Prisma.DocumentWhereInput['createdAt'];
|
||||
currentTeamMemberRole?: TeamMemberRole;
|
||||
search?: string;
|
||||
};
|
||||
|
||||
const getTeamCounts = async (options: GetTeamCountsOption) => {
|
||||
@@ -189,14 +162,6 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const searchFilter: Prisma.DocumentWhereInput = {
|
||||
OR: [
|
||||
{ title: { contains: options.search, mode: 'insensitive' } },
|
||||
{ Recipient: { some: { name: { contains: options.search, mode: 'insensitive' } } } },
|
||||
{ Recipient: { some: { email: { contains: options.search, mode: 'insensitive' } } } },
|
||||
],
|
||||
};
|
||||
|
||||
let ownerCountsWhereInput: Prisma.DocumentWhereInput = {
|
||||
userId: userIdWhereClause,
|
||||
createdAt,
|
||||
@@ -207,50 +172,6 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
|
||||
let notSignedCountsGroupByArgs = null;
|
||||
let hasSignedCountsGroupByArgs = null;
|
||||
|
||||
const visibilityFilters = [
|
||||
...match(options.currentTeamMemberRole)
|
||||
.with(TeamMemberRole.ADMIN, () => [
|
||||
{ visibility: DocumentVisibility.EVERYONE },
|
||||
{ visibility: DocumentVisibility.MANAGER_AND_ABOVE },
|
||||
{ visibility: DocumentVisibility.ADMIN },
|
||||
])
|
||||
.with(TeamMemberRole.MANAGER, () => [
|
||||
{ visibility: DocumentVisibility.EVERYONE },
|
||||
{ visibility: DocumentVisibility.MANAGER_AND_ABOVE },
|
||||
])
|
||||
.otherwise(() => [{ visibility: DocumentVisibility.EVERYONE }]),
|
||||
];
|
||||
|
||||
ownerCountsWhereInput = {
|
||||
...ownerCountsWhereInput,
|
||||
OR: [
|
||||
{
|
||||
AND: [
|
||||
{
|
||||
visibility: {
|
||||
in: visibilityFilters.map((filter) => filter.visibility),
|
||||
},
|
||||
},
|
||||
{
|
||||
Recipient: {
|
||||
none: {
|
||||
email: options.currentUserEmail,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
Recipient: {
|
||||
some: {
|
||||
email: options.currentUserEmail,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
...searchFilter,
|
||||
};
|
||||
|
||||
if (teamEmail) {
|
||||
ownerCountsWhereInput = {
|
||||
userId: userIdWhereClause,
|
||||
|
||||
@@ -3,13 +3,7 @@ import type { RequestMetadata } from '@documenso/lib/universal/extract-request-m
|
||||
import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import {
|
||||
DocumentSigningOrder,
|
||||
DocumentStatus,
|
||||
RecipientRole,
|
||||
SendStatus,
|
||||
SigningStatus,
|
||||
} from '@documenso/prisma/client';
|
||||
import { DocumentStatus, RecipientRole, SendStatus, SigningStatus } from '@documenso/prisma/client';
|
||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||
|
||||
import { jobs } from '../../jobs/client';
|
||||
@@ -63,9 +57,7 @@ export const sendDocument = async ({
|
||||
}),
|
||||
},
|
||||
include: {
|
||||
Recipient: {
|
||||
orderBy: [{ signingOrder: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],
|
||||
},
|
||||
Recipient: true,
|
||||
documentMeta: true,
|
||||
documentData: true,
|
||||
},
|
||||
@@ -83,21 +75,6 @@ export const sendDocument = async ({
|
||||
throw new Error('Can not send completed document');
|
||||
}
|
||||
|
||||
const signingOrder = document.documentMeta?.signingOrder || DocumentSigningOrder.PARALLEL;
|
||||
|
||||
let recipientsToNotify = document.Recipient;
|
||||
|
||||
if (signingOrder === DocumentSigningOrder.SEQUENTIAL) {
|
||||
// Get the currently active recipient.
|
||||
recipientsToNotify = document.Recipient.filter(
|
||||
(r) => r.signingStatus === SigningStatus.NOT_SIGNED && r.role !== RecipientRole.CC,
|
||||
).slice(0, 1);
|
||||
|
||||
// Secondary filter so we aren't resending if the current active recipient has already
|
||||
// received the document.
|
||||
recipientsToNotify.filter((r) => r.sendStatus !== SendStatus.SENT);
|
||||
}
|
||||
|
||||
const { documentData } = document;
|
||||
|
||||
if (!documentData.data) {
|
||||
@@ -158,7 +135,7 @@ export const sendDocument = async ({
|
||||
|
||||
if (sendEmail) {
|
||||
await Promise.all(
|
||||
recipientsToNotify.map(async (recipient) => {
|
||||
document.Recipient.map(async (recipient) => {
|
||||
if (recipient.sendStatus === SendStatus.SENT || recipient.role === RecipientRole.CC) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import type { RequestMetadata } from '@documenso/lib/universal/extract-request-m
|
||||
import type { CreateDocumentAuditLogDataResponse } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { DocumentVisibility } from '@documenso/prisma/client';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
@@ -20,7 +19,6 @@ export type UpdateDocumentSettingsOptions = {
|
||||
data: {
|
||||
title?: string;
|
||||
externalId?: string | null;
|
||||
visibility?: string | null;
|
||||
globalAccessAuth?: TDocumentAccessAuthTypes | null;
|
||||
globalActionAuth?: TDocumentActionAuthTypes | null;
|
||||
};
|
||||
@@ -93,14 +91,10 @@ export const updateDocumentSettings = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const isTitleSame = data.title === undefined || data.title === document.title;
|
||||
const isExternalIdSame = data.externalId === undefined || data.externalId === document.externalId;
|
||||
const isGlobalAccessSame =
|
||||
documentGlobalAccessAuth === undefined || documentGlobalAccessAuth === newGlobalAccessAuth;
|
||||
const isGlobalActionSame =
|
||||
documentGlobalActionAuth === undefined || documentGlobalActionAuth === newGlobalActionAuth;
|
||||
const isDocumentVisibilitySame =
|
||||
data.visibility === undefined || data.visibility === document.visibility;
|
||||
const isTitleSame = data.title === document.title;
|
||||
const isExternalIdSame = data.externalId === document.externalId;
|
||||
const isGlobalAccessSame = documentGlobalAccessAuth === newGlobalAccessAuth;
|
||||
const isGlobalActionSame = documentGlobalActionAuth === newGlobalActionAuth;
|
||||
|
||||
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
||||
|
||||
@@ -171,21 +165,6 @@ export const updateDocumentSettings = async ({
|
||||
);
|
||||
}
|
||||
|
||||
if (!isDocumentVisibilitySame) {
|
||||
auditLogs.push(
|
||||
createDocumentAuditLogData({
|
||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_VISIBILITY_UPDATED,
|
||||
documentId,
|
||||
user,
|
||||
requestMetadata,
|
||||
data: {
|
||||
from: document.visibility,
|
||||
to: data.visibility || '',
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Early return if nothing is required.
|
||||
if (auditLogs.length === 0) {
|
||||
return document;
|
||||
@@ -203,8 +182,7 @@ export const updateDocumentSettings = async ({
|
||||
},
|
||||
data: {
|
||||
title: data.title,
|
||||
externalId: data.externalId,
|
||||
visibility: data.visibility as DocumentVisibility,
|
||||
externalId: data.externalId || null,
|
||||
authOptions,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -5,7 +5,11 @@ import { getToken } from 'next-auth/jwt';
|
||||
import { LOCAL_FEATURE_FLAGS } from '@documenso/lib/constants/feature-flags';
|
||||
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
||||
|
||||
import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app';
|
||||
import {
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL,
|
||||
NEXT_PUBLIC_MARKETING_URL,
|
||||
NEXT_PUBLIC_WEBAPP_URL,
|
||||
} from '../../constants/app';
|
||||
import { extractDistinctUserId, mapJwtToFlagProperties } from './get';
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,11 @@ import { getToken } from 'next-auth/jwt';
|
||||
import { LOCAL_FEATURE_FLAGS, extractPostHogConfig } from '@documenso/lib/constants/feature-flags';
|
||||
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
||||
|
||||
import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app';
|
||||
import {
|
||||
NEXT_PRIVATE_INTERNAL_WEBAPP_URL,
|
||||
NEXT_PUBLIC_MARKETING_URL,
|
||||
NEXT_PUBLIC_WEBAPP_URL,
|
||||
} from '../../constants/app';
|
||||
|
||||
/**
|
||||
* Evaluate a single feature flag based on the current user if possible.
|
||||
@@ -67,7 +71,7 @@ export default async function handleFeatureFlagGet(req: Request) {
|
||||
if (origin.startsWith(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3001')) {
|
||||
res.headers.set('Access-Control-Allow-Origin', origin);
|
||||
}
|
||||
|
||||
|
||||
if (origin.startsWith(NEXT_PRIVATE_INTERNAL_WEBAPP_URL ?? 'http://localhost:3000')) {
|
||||
res.headers.set('Access-Control-Allow-Origin', origin);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { isDeepEqual } from 'remeda';
|
||||
|
||||
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
|
||||
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
|
||||
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
|
||||
@@ -22,15 +20,22 @@ import {
|
||||
} from '@documenso/lib/utils/document-audit-logs';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Field } from '@documenso/prisma/client';
|
||||
import { FieldType } from '@documenso/prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { canRecipientFieldsBeModified } from '../../utils/recipients';
|
||||
import { FieldType, SendStatus, SigningStatus } from '@documenso/prisma/client';
|
||||
|
||||
export interface SetFieldsForDocumentOptions {
|
||||
userId: number;
|
||||
documentId: number;
|
||||
fields: FieldData[];
|
||||
fields: {
|
||||
id?: number | null;
|
||||
type: FieldType;
|
||||
signerEmail: string;
|
||||
pageNumber: number;
|
||||
pageX: number;
|
||||
pageY: number;
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
fieldMeta?: FieldMeta;
|
||||
}[];
|
||||
requestMetadata?: RequestMetadata;
|
||||
}
|
||||
|
||||
@@ -58,9 +63,6 @@ export const setFieldsForDocument = async ({
|
||||
},
|
||||
],
|
||||
},
|
||||
include: {
|
||||
Recipient: true,
|
||||
},
|
||||
});
|
||||
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
@@ -95,36 +97,21 @@ export const setFieldsForDocument = async ({
|
||||
(existingField) => !fields.find((field) => field.id === existingField.id),
|
||||
);
|
||||
|
||||
const linkedFields = fields.map((field) => {
|
||||
const existing = existingFields.find((existingField) => existingField.id === field.id);
|
||||
const linkedFields = fields
|
||||
.map((field) => {
|
||||
const existing = existingFields.find((existingField) => existingField.id === field.id);
|
||||
|
||||
const recipient = document.Recipient.find(
|
||||
(recipient) => recipient.email.toLowerCase() === field.signerEmail.toLowerCase(),
|
||||
);
|
||||
|
||||
// Each field MUST have a recipient associated with it.
|
||||
if (!recipient) {
|
||||
throw new AppError(AppErrorCode.INVALID_REQUEST, `Recipient not found for field ${field.id}`);
|
||||
}
|
||||
|
||||
// Check whether the existing field can be modified.
|
||||
if (
|
||||
existing &&
|
||||
hasFieldBeenChanged(existing, field) &&
|
||||
!canRecipientFieldsBeModified(recipient, existingFields)
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_REQUEST,
|
||||
'Cannot modify a field where the recipient has already interacted with the document',
|
||||
return {
|
||||
...field,
|
||||
_persisted: existing,
|
||||
};
|
||||
})
|
||||
.filter((field) => {
|
||||
return (
|
||||
field._persisted?.Recipient?.sendStatus !== SendStatus.SENT &&
|
||||
field._persisted?.Recipient?.signingStatus !== SigningStatus.SIGNED
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...field,
|
||||
_persisted: existing,
|
||||
_recipient: recipient,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const persistedFields = await prisma.$transaction(async (tx) => {
|
||||
return await Promise.all(
|
||||
@@ -335,33 +322,3 @@ export const setFieldsForDocument = async ({
|
||||
|
||||
return [...filteredFields, ...persistedFields];
|
||||
};
|
||||
|
||||
/**
|
||||
* If you change this you MUST update the `hasFieldBeenChanged` function.
|
||||
*/
|
||||
type FieldData = {
|
||||
id?: number | null;
|
||||
type: FieldType;
|
||||
signerEmail: string;
|
||||
pageNumber: number;
|
||||
pageX: number;
|
||||
pageY: number;
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
fieldMeta?: FieldMeta;
|
||||
};
|
||||
|
||||
const hasFieldBeenChanged = (field: Field, newFieldData: FieldData) => {
|
||||
const currentFieldMeta = field.fieldMeta || null;
|
||||
const newFieldMeta = newFieldData.fieldMeta || null;
|
||||
|
||||
return (
|
||||
field.type !== newFieldData.type ||
|
||||
field.page !== newFieldData.pageNumber ||
|
||||
field.positionX.toNumber() !== newFieldData.pageX ||
|
||||
field.positionY.toNumber() !== newFieldData.pageY ||
|
||||
field.width.toNumber() !== newFieldData.pageWidth ||
|
||||
field.height.toNumber() !== newFieldData.pageHeight ||
|
||||
!isDeepEqual(currentFieldMeta, newFieldMeta)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,8 +4,5 @@ import { cookies } from 'next/headers';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export const switchI18NLanguage = async (lang: string) => {
|
||||
// Two year expiry.
|
||||
const maxAge = 60 * 60 * 24 * 365 * 2;
|
||||
|
||||
cookies().set('language', lang, { maxAge });
|
||||
cookies().set('language', lang);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { SendStatus } from '@documenso/prisma/client';
|
||||
|
||||
export type DeleteRecipientForTemplateOptions = {
|
||||
templateId: number;
|
||||
recipientId: number;
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
};
|
||||
|
||||
export const deleteRecipientFromTemplate = async ({
|
||||
templateId,
|
||||
recipientId,
|
||||
userId,
|
||||
teamId,
|
||||
}: DeleteRecipientForTemplateOptions) => {
|
||||
const recipient = await prisma.recipient.findFirst({
|
||||
where: {
|
||||
id: recipientId,
|
||||
Template: {
|
||||
id: templateId,
|
||||
...(teamId
|
||||
? {
|
||||
team: {
|
||||
id: teamId,
|
||||
members: {
|
||||
some: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
userId,
|
||||
teamId: null,
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!recipient) {
|
||||
throw new Error('Recipient not found');
|
||||
}
|
||||
|
||||
if (recipient.sendStatus !== SendStatus.NOT_SENT) {
|
||||
throw new Error('Can not delete a recipient that has already been sent a document');
|
||||
}
|
||||
|
||||
return await prisma.recipient.delete({
|
||||
where: {
|
||||
id: recipient.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1,46 +0,0 @@
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentSigningOrder, SigningStatus } from '@documenso/prisma/client';
|
||||
|
||||
export type GetIsRecipientTurnOptions = {
|
||||
token: string;
|
||||
};
|
||||
|
||||
export async function getIsRecipientsTurnToSign({ token }: GetIsRecipientTurnOptions) {
|
||||
const document = await prisma.document.findFirstOrThrow({
|
||||
where: {
|
||||
Recipient: {
|
||||
some: {
|
||||
token,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
documentMeta: true,
|
||||
Recipient: {
|
||||
orderBy: {
|
||||
signingOrder: 'asc',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (document.documentMeta?.signingOrder !== DocumentSigningOrder.SEQUENTIAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const recipients = document.Recipient;
|
||||
|
||||
const currentRecipientIndex = recipients.findIndex((r) => r.token === token);
|
||||
|
||||
if (currentRecipientIndex === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < currentRecipientIndex; i++) {
|
||||
if (recipients[i].signingStatus !== SigningStatus.SIGNED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
import { createElement } from 'react';
|
||||
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { mailer } from '@documenso/email/mailer';
|
||||
import { render } from '@documenso/email/render';
|
||||
import RecipientRemovedFromDocumentTemplate from '@documenso/email/templates/recipient-removed-from-document';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import {
|
||||
type TRecipientActionAuthTypes,
|
||||
@@ -21,16 +16,19 @@ import type { Recipient } from '@documenso/prisma/client';
|
||||
import { RecipientRole } from '@documenso/prisma/client';
|
||||
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
||||
import { FROM_ADDRESS, FROM_NAME } from '../../constants/email';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { canRecipientBeModified } from '../../utils/recipients';
|
||||
|
||||
export interface SetRecipientsForDocumentOptions {
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
documentId: number;
|
||||
recipients: RecipientData[];
|
||||
recipients: {
|
||||
id?: number | null;
|
||||
email: string;
|
||||
name: string;
|
||||
role: RecipientRole;
|
||||
actionAuth?: TRecipientActionAuthTypes | null;
|
||||
}[];
|
||||
requestMetadata?: RequestMetadata;
|
||||
}
|
||||
|
||||
@@ -60,9 +58,6 @@ export const setRecipientsForDocument = async ({
|
||||
teamId: null,
|
||||
}),
|
||||
},
|
||||
include: {
|
||||
Field: true,
|
||||
},
|
||||
});
|
||||
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
@@ -120,28 +115,25 @@ export const setRecipientsForDocument = async ({
|
||||
),
|
||||
);
|
||||
|
||||
const linkedRecipients = normalizedRecipients.map((recipient) => {
|
||||
const existing = existingRecipients.find(
|
||||
(existingRecipient) =>
|
||||
existingRecipient.id === recipient.id || existingRecipient.email === recipient.email,
|
||||
);
|
||||
|
||||
if (
|
||||
existing &&
|
||||
hasRecipientBeenChanged(existing, recipient) &&
|
||||
!canRecipientBeModified(existing, document.Field)
|
||||
) {
|
||||
throw new AppError(
|
||||
AppErrorCode.INVALID_REQUEST,
|
||||
'Cannot modify a recipient who has already interacted with the document',
|
||||
const linkedRecipients = normalizedRecipients
|
||||
.map((recipient) => {
|
||||
const existing = existingRecipients.find(
|
||||
(existingRecipient) =>
|
||||
existingRecipient.id === recipient.id || existingRecipient.email === recipient.email,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...recipient,
|
||||
_persisted: existing,
|
||||
};
|
||||
});
|
||||
return {
|
||||
...recipient,
|
||||
_persisted: existing,
|
||||
};
|
||||
})
|
||||
.filter((recipient) => {
|
||||
return (
|
||||
recipient._persisted?.role === RecipientRole.CC ||
|
||||
(recipient._persisted?.sendStatus !== SendStatus.SENT &&
|
||||
recipient._persisted?.signingStatus !== SigningStatus.SIGNED)
|
||||
);
|
||||
});
|
||||
|
||||
const persistedRecipients = await prisma.$transaction(async (tx) => {
|
||||
return await Promise.all(
|
||||
@@ -164,7 +156,6 @@ export const setRecipientsForDocument = async ({
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
documentId,
|
||||
sendStatus: recipient.role === RecipientRole.CC ? SendStatus.SENT : SendStatus.NOT_SENT,
|
||||
signingStatus:
|
||||
@@ -175,7 +166,6 @@ export const setRecipientsForDocument = async ({
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
documentId,
|
||||
sendStatus: recipient.role === RecipientRole.CC ? SendStatus.SENT : SendStatus.NOT_SENT,
|
||||
@@ -275,37 +265,6 @@ export const setRecipientsForDocument = async ({
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
// Send emails to deleted recipients.
|
||||
await Promise.all(
|
||||
removedRecipients.map(async (recipient) => {
|
||||
if (recipient.sendStatus !== SendStatus.SENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
const assetBaseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
|
||||
|
||||
const template = createElement(RecipientRemovedFromDocumentTemplate, {
|
||||
documentName: document.title,
|
||||
inviterName: user.name || undefined,
|
||||
assetBaseUrl,
|
||||
});
|
||||
|
||||
await mailer.sendMail({
|
||||
to: {
|
||||
address: recipient.email,
|
||||
name: recipient.name,
|
||||
},
|
||||
from: {
|
||||
name: FROM_NAME,
|
||||
address: FROM_ADDRESS,
|
||||
},
|
||||
subject: 'You have been removed from a document',
|
||||
html: render(template),
|
||||
text: render(template, { plainText: true }),
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Filter out recipients that have been removed or have been updated.
|
||||
@@ -322,27 +281,3 @@ export const setRecipientsForDocument = async ({
|
||||
|
||||
return [...filteredRecipients, ...persistedRecipients];
|
||||
};
|
||||
|
||||
/**
|
||||
* If you change this you MUST update the `hasRecipientBeenChanged` function.
|
||||
*/
|
||||
type RecipientData = {
|
||||
id?: number | null;
|
||||
email: string;
|
||||
name: string;
|
||||
role: RecipientRole;
|
||||
signingOrder?: number | null;
|
||||
actionAuth?: TRecipientActionAuthTypes | null;
|
||||
};
|
||||
|
||||
const hasRecipientBeenChanged = (recipient: Recipient, newRecipientData: RecipientData) => {
|
||||
const authOptions = ZRecipientAuthOptionsSchema.parse(recipient.authOptions);
|
||||
|
||||
return (
|
||||
recipient.email !== newRecipientData.email ||
|
||||
recipient.name !== newRecipientData.name ||
|
||||
recipient.role !== newRecipientData.role ||
|
||||
recipient.signingOrder !== newRecipientData.signingOrder ||
|
||||
authOptions.actionAuth !== newRecipientData.actionAuth
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,6 @@ export type SetRecipientsForTemplateOptions = {
|
||||
email: string;
|
||||
name: string;
|
||||
role: RecipientRole;
|
||||
signingOrder?: number | null;
|
||||
actionAuth?: TRecipientActionAuthTypes | null;
|
||||
}[];
|
||||
};
|
||||
@@ -163,7 +162,6 @@ export const setRecipientsForTemplate = async ({
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
templateId,
|
||||
authOptions,
|
||||
},
|
||||
@@ -171,7 +169,6 @@ export const setRecipientsForTemplate = async ({
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
templateId,
|
||||
authOptions,
|
||||
|
||||
@@ -18,7 +18,6 @@ export type UpdateRecipientOptions = {
|
||||
email?: string;
|
||||
name?: string;
|
||||
role?: RecipientRole;
|
||||
signingOrder?: number | null;
|
||||
actionAuth?: TRecipientActionAuthTypes | null;
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
@@ -31,7 +30,6 @@ export const updateRecipient = async ({
|
||||
email,
|
||||
name,
|
||||
role,
|
||||
signingOrder,
|
||||
actionAuth,
|
||||
userId,
|
||||
teamId,
|
||||
@@ -114,7 +112,6 @@ export const updateRecipient = async ({
|
||||
email: email?.toLowerCase() ?? recipient.email,
|
||||
name: name ?? recipient.name,
|
||||
role: role ?? recipient.role,
|
||||
signingOrder,
|
||||
authOptions: createRecipientAuthOptions({
|
||||
accessAuth: recipientAuthOptions.accessAuth,
|
||||
actionAuth: actionAuth ?? null,
|
||||
|
||||
@@ -6,8 +6,6 @@ export type GetTeamByIdOptions = {
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export type GetTeamResponse = Awaited<ReturnType<typeof getTeamById>>;
|
||||
|
||||
/**
|
||||
* Get a team given a teamId.
|
||||
*
|
||||
|
||||
@@ -10,7 +10,6 @@ export type CreateDocumentFromTemplateLegacyOptions = {
|
||||
name?: string;
|
||||
email: string;
|
||||
role?: RecipientRole;
|
||||
signingOrder?: number | null;
|
||||
}[];
|
||||
};
|
||||
|
||||
@@ -74,7 +73,6 @@ export const createDocumentFromTemplateLegacy = async ({
|
||||
email: recipient.email,
|
||||
name: recipient.name,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
})),
|
||||
},
|
||||
@@ -131,14 +129,12 @@ export const createDocumentFromTemplateLegacy = async ({
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
},
|
||||
create: {
|
||||
documentId: document.id,
|
||||
email: recipient.email,
|
||||
name: recipient.name,
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
token: nanoid(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Field } from '@documenso/prisma/client';
|
||||
import {
|
||||
DocumentSigningOrder,
|
||||
DocumentSource,
|
||||
type Field,
|
||||
type Recipient,
|
||||
RecipientRole,
|
||||
SendStatus,
|
||||
@@ -42,7 +41,6 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
id: number;
|
||||
name?: string;
|
||||
email: string;
|
||||
signingOrder?: number | null;
|
||||
}[];
|
||||
|
||||
/**
|
||||
@@ -56,7 +54,6 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
password?: string;
|
||||
dateFormat?: string;
|
||||
redirectUrl?: string;
|
||||
signingOrder?: DocumentSigningOrder;
|
||||
};
|
||||
requestMetadata?: RequestMetadata;
|
||||
};
|
||||
@@ -137,7 +134,6 @@ export const createDocumentFromTemplate = async ({
|
||||
name: foundRecipient ? foundRecipient.name ?? '' : templateRecipient.name,
|
||||
email: foundRecipient ? foundRecipient.email : templateRecipient.email,
|
||||
role: templateRecipient.role,
|
||||
signingOrder: foundRecipient?.signingOrder ?? templateRecipient.signingOrder,
|
||||
authOptions: templateRecipient.authOptions,
|
||||
};
|
||||
});
|
||||
@@ -154,7 +150,7 @@ export const createDocumentFromTemplate = async ({
|
||||
const document = await tx.document.create({
|
||||
data: {
|
||||
source: DocumentSource.TEMPLATE,
|
||||
externalId: externalId || template.externalId,
|
||||
externalId,
|
||||
templateId: template.id,
|
||||
userId,
|
||||
teamId: template.teamId,
|
||||
@@ -172,10 +168,6 @@ export const createDocumentFromTemplate = async ({
|
||||
password: override?.password || template.templateMeta?.password,
|
||||
dateFormat: override?.dateFormat || template.templateMeta?.dateFormat,
|
||||
redirectUrl: override?.redirectUrl || template.templateMeta?.redirectUrl,
|
||||
signingOrder:
|
||||
override?.signingOrder ||
|
||||
template.templateMeta?.signingOrder ||
|
||||
DocumentSigningOrder.PARALLEL,
|
||||
},
|
||||
},
|
||||
Recipient: {
|
||||
|
||||
@@ -33,7 +33,7 @@ export const updateTemplateSettings = async ({
|
||||
meta,
|
||||
data,
|
||||
}: UpdateTemplateSettingsOptions) => {
|
||||
if (Object.values(data).length === 0 && Object.keys(meta ?? {}).length === 0) {
|
||||
if (Object.values(data).length === 0) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, 'Missing data to update');
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export const updateTemplateSettings = async ({
|
||||
},
|
||||
data: {
|
||||
title: data.title,
|
||||
externalId: data.externalId,
|
||||
externalId: data.externalId || null,
|
||||
type: data.type,
|
||||
publicDescription: data.publicDescription,
|
||||
publicTitle: data.publicTitle,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2024-07-24 13:01+1000\n"
|
||||
"POT-Creation-Date: 2024-08-22 05:16+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-09-16 16:03\n"
|
||||
"PO-Revision-Date: 2024-09-05 06:04\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -60,12 +60,12 @@ msgstr "<0>Passkey erforderlich</0> - Der Empfänger muss ein Konto haben und de
|
||||
msgid "Add a document"
|
||||
msgstr "Dokument hinzufügen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:336
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:305
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:339
|
||||
msgid "Add a URL to redirect the user to once the document is signed"
|
||||
msgstr "Fügen Sie eine URL hinzu, um den Benutzer nach der Unterzeichnung des Dokuments weiterzuleiten"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:248
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:217
|
||||
msgid "Add an external ID to the document. This can be used to identify the document in external systems."
|
||||
msgstr "Fügen Sie dem Dokument eine externe ID hinzu. Diese kann verwendet werden, um das Dokument in externen Systemen zu identifizieren."
|
||||
|
||||
@@ -82,19 +82,19 @@ msgstr "Weitere Option hinzufügen"
|
||||
msgid "Add another value"
|
||||
msgstr "Weiteren Wert hinzufügen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:662
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:459
|
||||
msgid "Add myself"
|
||||
msgstr "Mich selbst hinzufügen"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:450
|
||||
msgid "Add Myself"
|
||||
msgstr "Mich hinzufügen"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:436
|
||||
msgid "Add Placeholder Recipient"
|
||||
msgstr "Platzhalterempfänger hinzufügen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:651
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:448
|
||||
msgid "Add Signer"
|
||||
msgstr "Unterzeichner hinzufügen"
|
||||
|
||||
@@ -110,12 +110,12 @@ msgstr "Text zum Feld hinzufügen"
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:230
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:199
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:238
|
||||
msgid "Advanced Options"
|
||||
msgstr "Erweiterte Optionen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:565
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:510
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:402
|
||||
msgid "Advanced settings"
|
||||
msgstr "Erweiterte Einstellungen"
|
||||
@@ -142,24 +142,20 @@ msgstr "Genehmigung"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:276
|
||||
msgid "Black"
|
||||
msgstr "Schwarz"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:290
|
||||
msgid "Blue"
|
||||
msgstr "Blau"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:287
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:193
|
||||
msgid "Cannot remove signer"
|
||||
msgstr "Unterzeichner kann nicht entfernt werden"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:221
|
||||
#~ msgid "Cannot update signer because they have already signed a field"
|
||||
#~ msgstr ""
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:164
|
||||
#~ msgid "Cannot remove signer"
|
||||
#~ msgstr "Unterzeichner kann nicht entfernt werden"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:17
|
||||
msgid "Cc"
|
||||
@@ -178,7 +174,7 @@ msgstr "CC'd"
|
||||
msgid "Character Limit"
|
||||
msgstr "Zeichenbeschränkung"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:993
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:932
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:788
|
||||
msgid "Checkbox"
|
||||
msgstr "Checkbox"
|
||||
@@ -207,7 +203,7 @@ msgstr "Schließen"
|
||||
msgid "Configure Direct Recipient"
|
||||
msgstr "Direkten Empfänger konfigurieren"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:566
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:511
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:403
|
||||
msgid "Configure the {0} field"
|
||||
msgstr "Konfigurieren Sie das Feld {0}"
|
||||
@@ -224,22 +220,22 @@ msgstr "In die Zwischenablage kopiert"
|
||||
msgid "Custom Text"
|
||||
msgstr "Benutzerdefinierter Text"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:889
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:828
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:684
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:271
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:240
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:279
|
||||
msgid "Date Format"
|
||||
msgstr "Datumsformat"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:393
|
||||
msgid "Direct link receiver"
|
||||
msgstr "Empfänger des direkten Links"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:62
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:174
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:166
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:151
|
||||
msgid "Document access"
|
||||
msgstr "Dokumentenzugriff"
|
||||
@@ -256,7 +252,7 @@ msgstr "Herunterladen"
|
||||
msgid "Drag & drop your PDF here."
|
||||
msgstr "Ziehen Sie Ihr PDF hierher."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1019
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:958
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:814
|
||||
msgid "Dropdown"
|
||||
msgstr "Dropdown"
|
||||
@@ -265,12 +261,13 @@ msgstr "Dropdown"
|
||||
msgid "Dropdown options"
|
||||
msgstr "Dropdown-Optionen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:837
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:776
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:272
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:500
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:330
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:337
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:632
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:296
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:303
|
||||
msgid "Email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
@@ -278,19 +275,10 @@ msgstr "E-Mail"
|
||||
msgid "Email Options"
|
||||
msgstr "E-Mail-Optionen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1082
|
||||
msgid "Empty field"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/template.ts:8
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Direktlink-Signierung aktivieren"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:401
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
|
||||
msgid "Enable signing order"
|
||||
msgstr "Aktiviere die Signaturreihenfolge"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:84
|
||||
msgid "Enter password"
|
||||
msgstr "Passwort eingeben"
|
||||
@@ -299,7 +287,7 @@ msgstr "Passwort eingeben"
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:241
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:210
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:249
|
||||
msgid "External ID"
|
||||
msgstr "Externe ID"
|
||||
@@ -334,7 +322,7 @@ msgstr "Zurück"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:297
|
||||
msgid "Green"
|
||||
msgstr "Grün"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:72
|
||||
msgid "I am a signer of this document"
|
||||
@@ -388,13 +376,12 @@ msgstr "Nachricht <0>(Optional)</0>"
|
||||
msgid "Min"
|
||||
msgstr "Min"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:863
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:802
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:298
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:535
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:541
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:364
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:658
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:327
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:333
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
@@ -410,12 +397,12 @@ msgstr "Muss unterzeichnen"
|
||||
msgid "Needs to view"
|
||||
msgstr "Muss sehen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:674
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:613
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:497
|
||||
msgid "No recipient matching this description was found."
|
||||
msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:690
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:629
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:513
|
||||
msgid "No recipients with this role"
|
||||
msgstr "Keine Empfänger mit dieser Rolle"
|
||||
@@ -440,7 +427,7 @@ msgstr "Kein Unterschriftsfeld gefunden"
|
||||
msgid "No value found."
|
||||
msgstr "Kein Wert gefunden."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:941
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:880
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:736
|
||||
msgid "Number"
|
||||
msgstr "Nummer"
|
||||
@@ -475,7 +462,7 @@ msgstr "Wählen Sie eine Zahl"
|
||||
msgid "Placeholder"
|
||||
msgstr "Platzhalter"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:967
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:906
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:762
|
||||
msgid "Radio"
|
||||
msgstr "Radio"
|
||||
@@ -497,21 +484,21 @@ msgid "Receives copy"
|
||||
msgstr "Erhält Kopie"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:215
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:184
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:169
|
||||
msgid "Recipient action authentication"
|
||||
msgstr "Empfängeraktion Authentifizierung"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:283
|
||||
msgid "Red"
|
||||
msgstr "Rot"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:329
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:298
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:332
|
||||
msgid "Redirect URL"
|
||||
msgstr "Weiterleitungs-URL"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1069
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:996
|
||||
msgid "Remove"
|
||||
msgstr "Entfernen"
|
||||
|
||||
@@ -573,8 +560,8 @@ msgstr "Unterschriftenkarte teilen"
|
||||
msgid "Share the Link"
|
||||
msgstr "Link teilen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:680
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:477
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:468
|
||||
msgid "Show advanced settings"
|
||||
msgstr "Erweiterte Einstellungen anzeigen"
|
||||
|
||||
@@ -582,7 +569,7 @@ msgstr "Erweiterte Einstellungen anzeigen"
|
||||
msgid "Sign"
|
||||
msgstr "Unterschreiben"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:785
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:724
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:323
|
||||
#: packages/ui/primitives/document-flow/field-icon.tsx:52
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:580
|
||||
@@ -630,7 +617,7 @@ msgstr "Einreichen"
|
||||
msgid "Template title"
|
||||
msgstr "Vorlagentitel"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:915
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:854
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:710
|
||||
msgid "Text"
|
||||
msgstr "Text"
|
||||
@@ -691,7 +678,7 @@ msgstr "Der Name des Unterzeichners"
|
||||
msgid "This can be overriden by setting the authentication requirements directly on each recipient in the next step."
|
||||
msgstr "Dies kann überschrieben werden, indem die Authentifizierungsanforderungen im nächsten Schritt direkt für jeden Empfänger festgelegt werden."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:746
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:685
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
msgstr "Dieses Dokument wurde bereits an diesen Empfänger gesendet. Sie können diesen Empfänger nicht mehr bearbeiten."
|
||||
|
||||
@@ -699,36 +686,28 @@ msgstr "Dieses Dokument wurde bereits an diesen Empfänger gesendet. Sie können
|
||||
msgid "This document is password protected. Please enter the password to view the document."
|
||||
msgstr "Dieses Dokument ist durch ein Passwort geschützt. Bitte geben Sie das Passwort ein, um das Dokument anzusehen."
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:396
|
||||
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
|
||||
msgstr "Dieses Feld kann nicht geändert oder gelöscht werden. Wenn Sie den direkten Link dieser Vorlage teilen oder zu Ihrem öffentlichen Profil hinzufügen, kann jeder, der darauf zugreift, seinen Namen und seine E-Mail-Adresse eingeben und die ihm zugewiesenen Felder ausfüllen."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1050
|
||||
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:195
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:165
|
||||
#~ msgid "This signer has already received the document."
|
||||
#~ msgstr "Dieser Unterzeichner hat das Dokument bereits erhalten."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:194
|
||||
msgid "This signer has already signed the document."
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
|
||||
msgid "This will override any global settings."
|
||||
msgstr "Dies überschreibt alle globalen Einstellungen."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:305
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:274
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:309
|
||||
msgid "Time Zone"
|
||||
msgstr "Zeitzone"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:153
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:145
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1033
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:971
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:828
|
||||
msgid "To proceed further, please set at least one value for the {0} field."
|
||||
msgstr "Um fortzufahren, legen Sie bitte mindestens einen Wert für das Feld {0} fest."
|
||||
@@ -777,7 +756,7 @@ msgstr "Viewing"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:280
|
||||
#~ msgid "White"
|
||||
#~ msgstr "White"
|
||||
#~ msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:44
|
||||
msgid "You are about to send this document to the recipients. Are you sure you want to continue?"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,38 +1,33 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2024-07-24 13:01+1000\n"
|
||||
"POT-Creation-Date: 2024-08-22 05:16+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-09-16 14:04\n"
|
||||
"PO-Revision-Date: 2024-09-05 06:04\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: documenso-app\n"
|
||||
"X-Crowdin-Project-ID: 694691\n"
|
||||
"X-Crowdin-Language: de\n"
|
||||
"X-Crowdin-File: marketing.po\n"
|
||||
"X-Crowdin-File-ID: 6\n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:45
|
||||
msgid "{0}"
|
||||
msgstr "{0}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:100
|
||||
msgid "5 standard documents per month"
|
||||
msgstr "5 Standarddokumente pro Monat"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:198
|
||||
msgid "5 Users Included"
|
||||
msgstr "5 Benutzer inbegriffen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:34
|
||||
msgid "A 10x better signing experience."
|
||||
msgstr "Eine 10x bessere Signaturerfahrung."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:51
|
||||
msgid "Add document"
|
||||
@@ -40,142 +35,138 @@ msgstr "Dokument hinzufügen"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:201
|
||||
msgid "Add More Users for {0}"
|
||||
msgstr "Mehr Benutzer hinzufügen für {0}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:165
|
||||
msgid "All our metrics, finances, and learnings are public. We believe in transparency and want to share our journey with you. You can read more about why here: <0>Announcing Open Metrics</0>"
|
||||
msgstr "Alle unsere Kennzahlen, Finanzen und Erkenntnisse sind öffentlich. Wir glauben an Transparenz und möchten unsere Reise mit Ihnen teilen. Mehr erfahren Sie hier: <0>Ankündigung Offene Kennzahlen</0>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:58
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:65
|
||||
msgid "Amount Raised"
|
||||
msgstr "Erhobener Betrag"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:145
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:189
|
||||
msgid "API Access"
|
||||
msgstr "API-Zugriff"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:67
|
||||
msgid "Beautiful."
|
||||
msgstr "Schön."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:69
|
||||
msgid "Because signing should be celebrated. That’s why we care about the smallest detail in our product."
|
||||
msgstr "Weil Unterschriften gefeiert werden sollten. Deshalb kümmern wir uns um jedes kleinste Detail in unserem Produkt."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:35
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:57
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:36
|
||||
msgid "Blog"
|
||||
msgstr "Blog"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:64
|
||||
msgid "Build on top."
|
||||
msgstr "Aufbauen oben drauf."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:163
|
||||
msgid "Can I use Documenso commercially?"
|
||||
msgstr "Kann ich Documenso kommerziell nutzen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:42
|
||||
msgid "Careers"
|
||||
msgstr "Karrieren"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:36
|
||||
msgid "Changelog"
|
||||
msgstr "Änderungsprotokoll"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:85
|
||||
msgid "Choose a template from the community app store. Or submit your own template for others to use."
|
||||
msgstr "Wählen Sie eine Vorlage aus dem Community-App-Store. Oder reichen Sie Ihre eigene Vorlage ein, damit andere sie benutzen können."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:219
|
||||
msgid "Community"
|
||||
msgstr "Gemeinschaft"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-completed-documents-chart.tsx:55
|
||||
msgid "Completed Documents"
|
||||
msgstr "Fertige Dokumente"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-completed-documents-chart.tsx:33
|
||||
msgid "Completed Documents per Month"
|
||||
msgstr "Fertige Dokumente pro Monat"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:65
|
||||
msgid "Connections"
|
||||
msgstr "Verbindungen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:35
|
||||
msgid "Contact Us"
|
||||
msgstr "Kontaktiere uns"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:67
|
||||
msgid "Create connections and automations with Zapier and more to integrate with your favorite tools."
|
||||
msgstr "Erstellen Sie Verbindungen und Automatisierungen mit Zapier und mehr, um sich mit Ihren Lieblingstools zu integrieren."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:23
|
||||
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
|
||||
msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit der Nutzung modernster Dokumentensignaturen. Offene und schöne Signaturen sind zum Greifen nah."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/tooltip.tsx:35
|
||||
msgid "Customers with an Active Subscriptions."
|
||||
msgstr "Kunden mit einer aktiven Abonnements."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:33
|
||||
msgid "Customise and expand."
|
||||
msgstr "Anpassen und erweitern."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:38
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:44
|
||||
msgid "Designed for every stage of your journey."
|
||||
msgstr "Entwickelt für jede Phase Ihrer Reise."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:40
|
||||
msgid "Direct Link"
|
||||
msgstr "Direktlink"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:181
|
||||
msgid "Documenso is a community effort to create an open and vibrant ecosystem around a tool, everybody is free to use and adapt. By being truly open we want to create trusted infrastructure for the future of the internet."
|
||||
msgstr "Documenso ist eine Gemeinschaftsanstrengung, um ein offenes und lebendiges Ökosystem um ein Werkzeug zu schaffen, das jeder frei nutzen und anpassen kann. Indem wir wirklich offen sind, wollen wir vertrauenswürdige Infrastruktur für die Zukunft des Internets schaffen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:28
|
||||
msgid "Documenso on X"
|
||||
msgstr "Documenso auf X"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:104
|
||||
msgid "Document signing,<0/>finally open source."
|
||||
msgstr "Unterschriften,<0/>endlich Open Source."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:33
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:50
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:28
|
||||
msgid "Documentation"
|
||||
msgstr "Dokumentation"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:110
|
||||
msgid "Easily embed Documenso into your product. Simply copy and paste our react widget into your application."
|
||||
msgstr "Betten Sie Documenso ganz einfach in Ihr Produkt ein. Kopieren und fügen Sie einfach unser React-Widget in Ihre Anwendung ein."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:42
|
||||
#~ msgid "Easy Sharing (Soon)."
|
||||
#~ msgstr "Easy Sharing (Soon)."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:46
|
||||
msgid "Easy Sharing."
|
||||
msgstr "Einfaches Teilen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:148
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:192
|
||||
msgid "Email and Discord Support"
|
||||
msgstr "E-Mail- und Discord-Support"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:43
|
||||
msgid "Engagement"
|
||||
msgstr "Beteiligung"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:64
|
||||
msgid "Enter your details."
|
||||
@@ -183,272 +174,266 @@ msgstr "Geben Sie Ihre Details ein."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:16
|
||||
msgid "Enterprise Compliance, License or Technical Needs?"
|
||||
msgstr "Enterprise-Konformität, Lizenz- oder technische Bedürfnisse?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:128
|
||||
msgid "Everything you need for a great signing experience."
|
||||
msgstr "Alles, was Sie für ein großartiges Signaturerlebnis benötigen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:45
|
||||
msgid "Fast."
|
||||
msgstr "Schnell."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:36
|
||||
msgid "Faster, smarter and more beautiful."
|
||||
msgstr "Schneller, intelligenter und schöner."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:210
|
||||
msgid "Finances"
|
||||
msgstr "Finanzen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:38
|
||||
msgid "Follow us on X"
|
||||
msgstr "Folgen Sie uns auf X"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:172
|
||||
msgid "For companies looking to scale across multiple teams."
|
||||
msgstr "Für Unternehmen, die über mehrere Teams skalieren möchten."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:85
|
||||
msgid "For small teams and individuals with basic needs."
|
||||
msgstr "Für kleine Teams und Einzelpersonen mit grundlegenden Bedürfnissen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:80
|
||||
msgid "Free"
|
||||
msgstr "Kostenlos"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:26
|
||||
msgid "From the blog"
|
||||
msgstr "Aus dem Blog"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:9
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:17
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:33
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:41
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:49
|
||||
msgid "Full-Time"
|
||||
msgstr "Vollzeit"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:87
|
||||
msgid "Get paid (Soon)."
|
||||
msgstr "Lassen Sie sich bezahlen (Bald)."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:31
|
||||
msgid "Get started"
|
||||
msgstr "Loslegen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:75
|
||||
msgid "Get Started"
|
||||
msgstr "Loslegen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:47
|
||||
msgid "Get started today."
|
||||
msgstr "Fangen Sie heute an."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:30
|
||||
msgid "Get the latest news from Documenso, including product updates, team announcements and more!"
|
||||
msgstr "Erhalten Sie die neuesten Nachrichten von Documenso, einschließlich Produkt-Updates, Team-Ankündigungen und mehr!"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:233
|
||||
msgid "GitHub: Total Merged PRs"
|
||||
msgstr "GitHub: Gesamte PRs zusammengeführt"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:251
|
||||
msgid "GitHub: Total Open Issues"
|
||||
msgstr "GitHub: Gesamte offene Issues"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:225
|
||||
msgid "GitHub: Total Stars"
|
||||
msgstr "GitHub: Gesamtanzahl Sterne"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:23
|
||||
msgid "Global Salary Bands"
|
||||
msgstr "Globale Gehaltsbänder"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:261
|
||||
msgid "Growth"
|
||||
msgstr "Wachstum"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:134
|
||||
msgid "How can I contribute?"
|
||||
msgstr "Wie kann ich beitragen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:105
|
||||
msgid "How do you handle my data?"
|
||||
msgstr "Wie gehen Sie mit meinen Daten um?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:118
|
||||
msgid "Individual"
|
||||
msgstr "Einzelperson"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:89
|
||||
msgid "Integrated payments with Stripe so you don’t have to worry about getting paid."
|
||||
msgstr "Integrierte Zahlungen mit Stripe, sodass Sie sich keine Sorgen ums Bezahlen machen müssen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:35
|
||||
msgid "Integrates with all your favourite tools."
|
||||
msgstr "Integriert sich mit all Ihren Lieblingstools."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:289
|
||||
msgid "Is there more?"
|
||||
msgstr "Gibt es mehr?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:44
|
||||
msgid "It’s up to you. Either clone our repository or rely on our easy to use hosting solution."
|
||||
msgstr "Es liegt an Ihnen. Entweder klonen Sie unser Repository oder nutzen unsere einfach zu bedienende Hosting-Lösung."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:49
|
||||
msgid "Join Date"
|
||||
msgstr "Eintrittsdatum"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:19
|
||||
msgid "Join the Open Signing Movement"
|
||||
msgstr "Treten Sie der Open Signing-Bewegung bei"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:46
|
||||
msgid "Location"
|
||||
msgstr "Standort"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:66
|
||||
msgid "Make it your own through advanced customization and adjustability."
|
||||
msgstr "Machen Sie es zu Ihrem eigenen durch erweiterte Anpassung und Einstellbarkeit."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:199
|
||||
msgid "Merged PR's"
|
||||
msgstr "Zusammengeführte PRs"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:234
|
||||
msgid "Merged PRs"
|
||||
msgstr "Zusammengeführte PRs"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:40
|
||||
msgid "Monthly"
|
||||
msgstr "Monatlich"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:34
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:43
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:52
|
||||
msgid "New Users"
|
||||
msgstr "Neue Benutzer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:106
|
||||
msgid "No credit card required"
|
||||
msgstr "Keine Kreditkarte erforderlich"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/callout.tsx:29
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:125
|
||||
msgid "No Credit Card required"
|
||||
msgstr "Keine Kreditkarte erforderlich"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:61
|
||||
msgid "None of these work for you? Try self-hosting!"
|
||||
msgstr "Keines dieser Angebote passt zu Ihnen? Versuchen Sie das Selbst-Hosting!"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:194
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:252
|
||||
msgid "Open Issues"
|
||||
msgstr "Offene Issues"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:42
|
||||
msgid "Open Source or Hosted."
|
||||
msgstr "Open Source oder Hosted."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:161
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:37
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:64
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:40
|
||||
msgid "Open Startup"
|
||||
msgstr "Offenes Startup"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:41
|
||||
msgid "OSS Friends"
|
||||
msgstr "OSS-Freunde"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:91
|
||||
msgid "Our custom templates come with smart rules that can help you save time and energy."
|
||||
msgstr "Unsere benutzerdefinierten Vorlagen verfügen über intelligente Regeln, die Ihnen Zeit und Energie sparen können."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:20
|
||||
msgid "Our Enterprise License is great for large organizations looking to switch to Documenso for all their signing needs. It's available for our cloud offering as well as self-hosted setups and offers a wide range of compliance and Adminstration Features."
|
||||
msgstr "Unsere Enterprise-Lizenz ist ideal für große Organisationen, die auf Documenso für all ihre Signaturanforderungen umsteigen möchten. Sie ist sowohl für unser Cloud-Angebot als auch für selbstgehostete Setups verfügbar und bietet eine breite Palette an Compliance- und Verwaltungsfunktionen."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:20
|
||||
#~ msgid "Our Enterprise License is great large organizations looking to switch to Documenso for all their signing needs. It's availible for our cloud offering as well as self-hosted setups and offer a wide range of compliance and Adminstration Features."
|
||||
#~ msgstr "Our Enterprise License is great large organizations looking to switch to Documenso for all their signing needs. It's availible for our cloud offering as well as self-hosted setups and offer a wide range of compliance and Adminstration Features."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:65
|
||||
msgid "Our self-hosted option is great for small teams and individuals who need a simple solution. You can use our docker based setup to get started in minutes. Take control with full customizability and data ownership."
|
||||
msgstr "Unsere selbstgehostete Option ist ideal für kleine Teams und Einzelpersonen, die eine einfache Lösung benötigen. Sie können unser docker-basiertes Setup verwenden, um in wenigen Minuten loszulegen. Übernehmen Sie die Kontrolle mit vollständiger Anpassbarkeit und Datenhoheit."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#~ msgid "Part-Time"
|
||||
#~ msgstr "Teilzeit"
|
||||
msgid "Part-Time"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:151
|
||||
msgid "Premium Profile Name"
|
||||
msgstr "Premium Profilname"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:40
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:31
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:42
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:24
|
||||
msgid "Pricing"
|
||||
msgstr "Preise"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:43
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:53
|
||||
msgid "Privacy"
|
||||
msgstr "Datenschutz"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:58
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:108
|
||||
msgid "React Widget (Soon)."
|
||||
msgstr "React Widget (Demnächst)."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:48
|
||||
msgid "Receive your personal link to share with everyone you care about."
|
||||
msgstr "Erhalten Sie Ihren persönlichen Link zum Teilen mit allen, die Ihnen wichtig sind."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:37
|
||||
msgid "Role"
|
||||
msgstr "Rolle"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:37
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:40
|
||||
msgid "Salary"
|
||||
msgstr "Gehalt"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:62
|
||||
msgid "Save $60 or $120"
|
||||
msgstr "Sparen Sie $60 oder $120"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/i18n-switcher.tsx:47
|
||||
#~ msgid "Search languages..."
|
||||
#~ msgstr "Search languages..."
|
||||
#~ msgstr "Sprachen suchen...>>>>>>> main"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:109
|
||||
msgid "Securely. Our data centers are located in Frankfurt (Germany), giving us the best local privacy laws. We are very aware of the sensitive nature of our data and follow best practices to ensure the security and integrity of the data entrusted to us."
|
||||
msgstr "Sicher. Unsere Rechenzentren befinden sich in Frankfurt (Deutschland) und bieten uns die besten lokalen Datenschutzgesetze. Uns ist die sensible Natur unserer Daten sehr bewusst und wir folgen bewährten Praktiken, um die Sicherheit und Integrität der uns anvertrauten Daten zu gewährleisten."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:37
|
||||
msgid "Send, connect, receive and embed everywhere."
|
||||
msgstr "Überall senden, verbinden, empfangen und einbetten."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:34
|
||||
msgid "Seniority"
|
||||
msgstr "Dienstalter"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:39
|
||||
msgid "Shop"
|
||||
msgstr "Shop"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:63
|
||||
msgid "Sign"
|
||||
@@ -457,115 +442,115 @@ msgstr "Signieren"
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:72
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:61
|
||||
msgid "Sign in"
|
||||
msgstr "Anmelden"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:77
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:57
|
||||
msgid "Sign up"
|
||||
msgstr "Registrieren"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:22
|
||||
msgid "Signing Process"
|
||||
msgstr "Signaturprozess"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:94
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:136
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:180
|
||||
msgid "Signup Now"
|
||||
msgstr "Jetzt registrieren"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:89
|
||||
msgid "Smart."
|
||||
msgstr "Intelligent."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:132
|
||||
msgid "Star on GitHub"
|
||||
msgstr "Auf GitHub favorisieren"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:226
|
||||
msgid "Stars"
|
||||
msgstr "Favoriten"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:40
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:44
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:34
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:48
|
||||
msgid "Support"
|
||||
msgstr "Support"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:26
|
||||
msgid "Team"
|
||||
msgstr "Team"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:195
|
||||
msgid "Team Inbox"
|
||||
msgstr "Team-Posteingang"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:28
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:162
|
||||
msgid "Teams"
|
||||
msgstr "Teams"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:83
|
||||
msgid "Template Store (Soon)."
|
||||
msgstr "Vorlagen-Shop (Demnächst)."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:138
|
||||
msgid "That's awesome. You can take a look at the current <0>Issues</0> and join our <1>Discord Community</1> to keep up to date, on what the current priorities are. In any case, we are an open community and welcome all input, technical and non-technical ❤️"
|
||||
msgstr "Das ist großartig. Sie können sich die aktuellen <0>Issues</0> ansehen und unserer <1>Discord-Community</1> beitreten, um auf dem neuesten Stand zu bleiben, was die aktuellen Prioritäten sind. In jedem Fall sind wir eine offene Gemeinschaft und begrüßen jegliche Beiträge, technische und nicht-technische ❤️"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:293
|
||||
msgid "This page is evolving as we learn what makes a great signing company. We'll update it when we have more to share."
|
||||
msgstr "Diese Seite entwickelt sich weiter, während wir lernen, was ein großartiges Signing-Unternehmen ausmacht. Wir werden sie aktualisieren, wenn wir mehr zu teilen haben."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:31
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/total-signed-documents-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/total-signed-documents-chart.tsx:55
|
||||
msgid "Total Completed Documents"
|
||||
msgstr "Insgesamt Abgeschlossene Dokumente"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:267
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:268
|
||||
msgid "Total Customers"
|
||||
msgstr "Insgesamt Kunden"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:29
|
||||
msgid "Total Funding Raised"
|
||||
msgstr "Insgesamt Finanzierungsvolumen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:43
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:52
|
||||
msgid "Total Users"
|
||||
msgstr "Gesamtanzahl der Benutzer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:31
|
||||
msgid "Truly your own."
|
||||
msgstr "Wirklich Ihr Eigenes."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/callout.tsx:27
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:123
|
||||
msgid "Try our Free Plan"
|
||||
msgstr "Probieren Sie unseren Gratisplan aus"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:20
|
||||
msgid "Twitter Stats"
|
||||
msgstr "Twitter-Statistiken"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:142
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:186
|
||||
msgid "Unlimited Documents per Month"
|
||||
msgstr "Unbegrenzte Dokumente pro Monat"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:103
|
||||
msgid "Up to 10 recipients per document"
|
||||
msgstr "Bis zu 10 Empfänger pro Dokument"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:52
|
||||
msgid "Upload a document and add fields."
|
||||
@@ -573,48 +558,52 @@ msgstr "Laden Sie ein Dokument hoch und fügen Sie Felder hinzu."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:123
|
||||
msgid "Using our hosted version is the easiest way to get started, you can simply subscribe and start signing your documents. We take care of the infrastructure, so you can focus on your business. Additionally, when using our hosted version you benefit from our trusted signing certificates which helps you to build trust with your customers."
|
||||
msgstr "Die Nutzung unserer gehosteten Version ist der einfachste Weg, um zu starten. Sie können einfach abonnieren und mit der Unterzeichnung Ihrer Dokumente beginnen. Wir kümmern uns um die Infrastruktur, damit Sie sich auf Ihr Geschäft konzentrieren können. Zudem profitieren Sie bei der Nutzung unserer gehosteten Version von unseren vertrauenswürdigen Signaturzertifikaten, die Ihnen helfen, Vertrauen bei Ihren Kunden aufzubauen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:33
|
||||
msgid "View all stats"
|
||||
msgstr "Alle Statistiken anzeigen"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:195
|
||||
msgid "We are happy to assist you at <0>support@documenso.com</0> or <1>in our Discord-Support-Channel</1> please message either Lucas or Timur to get added to the channel if you are not already a member."
|
||||
msgstr "Wir helfen Ihnen gerne unter <0>support@documenso.com</0> oder <1>in unserem Discord-Support-Kanal</1>. Bitte senden Sie Lucas oder Timur eine Nachricht, um dem Kanal beizutreten, falls Sie noch kein Mitglied sind."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:89
|
||||
msgid "What is the difference between the plans?"
|
||||
msgstr "Was ist der Unterschied zwischen den Plänen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:47
|
||||
msgid "When it comes to sending or receiving a contract, you can count on lightning-fast speeds."
|
||||
msgstr "Wenn es um das Senden oder Empfangen eines Vertrags geht, können Sie auf blitzschnelle Geschwindigkeiten zählen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:191
|
||||
msgid "Where can I get support?"
|
||||
msgstr "Wo kann ich Unterstützung bekommen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:177
|
||||
msgid "Why should I prefer Documenso over DocuSign or some other signing tool?"
|
||||
msgstr "Warum sollte ich Documenso gegenüber DocuSign oder einem anderen Signatur-Tool bevorzugen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:119
|
||||
msgid "Why should I use your hosting service?"
|
||||
msgstr "Warum sollte ich Ihren Hosting-Service nutzen?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:60
|
||||
msgid "Yearly"
|
||||
msgstr "Jährlich"
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:167
|
||||
msgid "Yes! Documenso is offered under the GNU AGPL V3 open source license. This means you can use it for free and even modify it to fit your needs, as long as you publish your changes under the same license."
|
||||
msgstr "Ja! Documenso wird unter der GNU AGPL V3 Open-Source-Lizenz angeboten. Das bedeutet, dass Sie es kostenlos nutzen und sogar an Ihre Bedürfnisse anpassen können, solange Sie Ihre Änderungen unter derselben Lizenz veröffentlichen."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:93
|
||||
msgid "You can self-host Documenso for free or use our ready-to-use hosted version. The hosted version comes with additional support, painless scalability and more. Early adopters will get access to all features we build this year, for no additional cost! Forever! Yes, that includes multiple users per account later. If you want Documenso for your enterprise, we are happy to talk about your needs."
|
||||
msgstr "Sie können Documenso kostenlos selbst hosten oder unsere sofort einsatzbereite gehostete Version nutzen. Die gehostete Version bietet zusätzlichen Support, schmerzfreie Skalierbarkeit und mehr. Frühzeitige Anwender erhalten in diesem Jahr Zugriff auf alle Funktionen, die wir entwickeln, ohne zusätzliche Kosten! Für immer! Ja, das beinhaltet später mehrere Benutzer pro Konto. Wenn Sie Documenso für Ihr Unternehmen möchten, sprechen wir gerne über Ihre Bedürfnisse."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:265
|
||||
msgid "Your browser does not support the video tag."
|
||||
msgstr "Ihr Browser unterstützt das Video-Tag nicht."
|
||||
msgstr ""
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:265
|
||||
#~ msgid "Your browser does not support the video tag.<<<<<<< HEAD"
|
||||
#~ msgstr "Ihr Browser unterstützt das Video-Tag nicht.>>>>>>> main"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2024-07-24 13:01+1000\n"
|
||||
"POT-Creation-Date: 2024-08-22 05:16+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-09-16 16:03\n"
|
||||
"PO-Revision-Date: 2024-09-05 06:04\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -26,15 +26,15 @@ msgstr "\"{0}\" wird im Dokument erscheinen, da es eine Zeitzone von \"{timezone
|
||||
msgid "\"{documentTitle}\" has been successfully deleted"
|
||||
msgstr "\"{documentTitle}\" wurde erfolgreich gelöscht"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:78
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:76
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu genehmigen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:75
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:73
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu unterzeichnen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:72
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:70
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) hat dich eingeladen, dieses Dokument zu betrachten"
|
||||
|
||||
@@ -60,11 +60,11 @@ msgstr "{0, plural, one {# Sitz} other {# Sitze}}"
|
||||
msgid "{0, plural, one {<0>You have <1>1</1> pending team invitation</0>} other {<2>You have <3>#</3> pending team invitations</2>}}"
|
||||
msgstr "{0, plural, one {<0>Du hast <1>1</1> ausstehende Team-Einladung</0>} other {<2>Du hast <3>#</3> ausstehende Team-Einladungen</2>}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:102
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Empfänger} other {# Empfänger}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:204
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {Warte auf 1 Empfänger} other {Warte auf # Empfänger}}"
|
||||
|
||||
@@ -84,7 +84,7 @@ msgstr "{0} Dokument"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} von {1} Dokumenten verbleibend in diesem Monat."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:165
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:139
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Empfänger(in) / -n"
|
||||
|
||||
@@ -220,7 +220,7 @@ msgstr "Aktive Abonnements"
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:157
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:143
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:87
|
||||
msgid "Add all relevant fields for each recipient."
|
||||
msgstr "Fügen Sie alle relevanten Felder für jeden Empfänger hinzu."
|
||||
@@ -241,7 +241,7 @@ msgstr "Fügen Sie einen Authenticator hinzu, um als sekundäre Authentifizierun
|
||||
msgid "Add email"
|
||||
msgstr "E-Mail hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:156
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:142
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:86
|
||||
msgid "Add Fields"
|
||||
msgstr "Felder hinzufügen"
|
||||
@@ -251,8 +251,8 @@ msgid "Add more"
|
||||
msgstr "Mehr hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:270
|
||||
#~ msgid "Add number"
|
||||
#~ msgstr "Add number"
|
||||
msgid "Add number"
|
||||
msgstr "Nummer hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:146
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:154
|
||||
@@ -263,11 +263,11 @@ msgstr "Passkey hinzufügen"
|
||||
msgid "Add Placeholders"
|
||||
msgstr "Platzhalter hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:151
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:137
|
||||
msgid "Add Signers"
|
||||
msgstr "Unterzeichner hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:161
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:147
|
||||
msgid "Add Subject"
|
||||
msgstr "Betreff hinzufügen"
|
||||
|
||||
@@ -276,14 +276,14 @@ msgid "Add team email"
|
||||
msgstr "Team-E-Mail hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:256
|
||||
#~ msgid "Add text"
|
||||
#~ msgstr "Add text"
|
||||
msgid "Add text"
|
||||
msgstr "Text hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:272
|
||||
#~ msgid "Add Text"
|
||||
#~ msgstr "Add Text"
|
||||
msgid "Add Text"
|
||||
msgstr "Text hinzufügen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:152
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:138
|
||||
msgid "Add the people who will sign the document."
|
||||
msgstr "Fügen Sie die Personen hinzu, die das Dokument unterschreiben werden."
|
||||
|
||||
@@ -291,7 +291,7 @@ msgstr "Fügen Sie die Personen hinzu, die das Dokument unterschreiben werden."
|
||||
msgid "Add the recipients to create the document with"
|
||||
msgstr "Fügen Sie die Empfänger hinzu, um das Dokument zu erstellen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:162
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:148
|
||||
msgid "Add the subject and message you wish to send to signers."
|
||||
msgstr "Fügen Sie den Betreff und die Nachricht hinzu, die Sie den Unterzeichnern senden möchten."
|
||||
|
||||
@@ -339,7 +339,7 @@ msgstr "Alle Zeiten"
|
||||
msgid "Allows authenticating using biometrics, password managers, hardware keys, etc."
|
||||
msgstr "Erlaubt die Authentifizierung mit biometrischen Daten, Passwort-Managern, Hardware-Schlüsseln usw."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:423
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:411
|
||||
msgid "Already have an account? <0>Sign in instead</0>"
|
||||
msgstr "Hast du bereits ein Konto? <0>Stattdessen anmelden</0>"
|
||||
|
||||
@@ -370,13 +370,13 @@ msgstr "Eine E-Mail, in der die Übertragung dieses Teams angefordert wird, wurd
|
||||
msgid "An error occurred"
|
||||
msgstr "Ein Fehler ist aufgetreten"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:248
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:197
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:231
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:226
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:176
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:210
|
||||
msgid "An error occurred while adding signers."
|
||||
msgstr "Ein Fehler ist aufgetreten, während Unterzeichner hinzugefügt wurden."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:278
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:256
|
||||
msgid "An error occurred while adding the fields."
|
||||
msgstr "Ein Fehler ist aufgetreten, während die Felder hinzugefügt wurden."
|
||||
|
||||
@@ -434,7 +434,7 @@ msgstr "Ein Fehler ist aufgetreten, während die Unterschrift entfernt wurde."
|
||||
msgid "An error occurred while removing the text."
|
||||
msgstr "Ein Fehler ist aufgetreten, während der Text entfernt wurde."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:309
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:287
|
||||
msgid "An error occurred while sending the document."
|
||||
msgstr "Ein Fehler ist aufgetreten, während das Dokument gesendet wurde."
|
||||
|
||||
@@ -458,8 +458,8 @@ msgstr "Ein Fehler ist aufgetreten, während das Dokument unterzeichnet wurde."
|
||||
msgid "An error occurred while trying to create a checkout session."
|
||||
msgstr "Ein Fehler ist aufgetreten, während versucht wurde, eine Checkout-Sitzung zu erstellen."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:214
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:166
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:199
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:153
|
||||
msgid "An error occurred while updating the document settings."
|
||||
msgstr "Ein Fehler ist aufgetreten, während die Dokumenteinstellungen aktualisiert wurden."
|
||||
|
||||
@@ -539,7 +539,7 @@ msgstr "App-Version"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:144
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:122
|
||||
msgid "Approve"
|
||||
msgstr "Genehmigen"
|
||||
|
||||
@@ -578,7 +578,7 @@ msgid "Audit Log"
|
||||
msgstr "Audit-Protokoll"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:41
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:52
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:57
|
||||
msgid "Authentication required"
|
||||
msgstr "Authentifizierung erforderlich"
|
||||
|
||||
@@ -596,7 +596,7 @@ msgstr "Warte auf E-Mail-Bestätigung"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:369
|
||||
#: apps/web/src/components/(dashboard)/settings/layout/activity-back.tsx:20
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:509
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:497
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
@@ -609,7 +609,7 @@ msgid "Background Color"
|
||||
msgstr "Hintergrundfarbe"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167
|
||||
#: apps/web/src/components/forms/signin.tsx:485
|
||||
#: apps/web/src/components/forms/signin.tsx:473
|
||||
msgid "Backup Code"
|
||||
msgstr "Backup-Code"
|
||||
|
||||
@@ -621,7 +621,7 @@ msgstr "Backup-Codes"
|
||||
msgid "Banner Updated"
|
||||
msgstr "Banner aktualisiert"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:472
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:460
|
||||
msgid "Basic details"
|
||||
msgstr "Basisdetails"
|
||||
|
||||
@@ -662,13 +662,13 @@ msgstr "Durch die Aktivierung von 2FA müssen Sie jedes Mal, wenn Sie sich anmel
|
||||
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:119
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:470
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:178
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:71
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-passkey.tsx:164
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-passkey.tsx:189
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:143
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:327
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:110
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:250
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:333
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -720,7 +720,7 @@ msgstr "Wählen..."
|
||||
msgid "Claim account"
|
||||
msgstr "Konto beanspruchen"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:481
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:469
|
||||
msgid "Claim username"
|
||||
msgstr "Benutzername beanspruchen"
|
||||
|
||||
@@ -728,7 +728,7 @@ msgstr "Benutzername beanspruchen"
|
||||
msgid "Claim your profile later"
|
||||
msgstr "Profile später beanspruchen"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:279
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:267
|
||||
msgid "Claim your username now"
|
||||
msgstr "Benutzername jetzt beanspruchen"
|
||||
|
||||
@@ -752,7 +752,7 @@ msgid "Click to copy signing link for sending to recipient"
|
||||
msgstr "Klicken Sie, um den Signatur-Link zu kopieren, um ihn an den Empfänger zu senden"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:175
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:114
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:107
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:435
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:314
|
||||
msgid "Click to insert field"
|
||||
@@ -770,22 +770,22 @@ msgstr "Klicken Sie, um das Feld einzufügen"
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:58
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:425
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:304
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:522
|
||||
msgid "Complete"
|
||||
msgstr "Vollständig"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Approval"
|
||||
msgstr "Genehmigung abschließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:66
|
||||
msgid "Complete Signing"
|
||||
msgstr "Unterzeichnung abschließen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:65
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Betrachten abschließen"
|
||||
|
||||
@@ -802,7 +802,7 @@ msgstr "Abgeschlossene Dokumente"
|
||||
msgid "Completed Documents"
|
||||
msgstr "Abgeschlossene Dokumente"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:147
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:133
|
||||
msgid "Configure general settings for the document."
|
||||
msgstr "Konfigurieren Sie die allgemeinen Einstellungen für das Dokument."
|
||||
|
||||
@@ -887,7 +887,7 @@ msgstr "Token kopieren"
|
||||
msgid "Create"
|
||||
msgstr "Erstellen"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:264
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:252
|
||||
msgid "Create a new account"
|
||||
msgstr "Ein neues Konto erstellen"
|
||||
|
||||
@@ -952,11 +952,11 @@ msgstr "Webhook erstellen"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Webhook erstellen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:214
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit dem modernen Dokumentensignieren."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:268
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:256
|
||||
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
|
||||
msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit dem modernen Dokumentensignieren. Offenes und schönes Signieren liegt in Ihrer Reichweite."
|
||||
|
||||
@@ -986,12 +986,10 @@ msgstr "Erstellt am"
|
||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:88
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/webhooks/page.tsx:93
|
||||
msgid "Created on {0}"
|
||||
msgstr "Erstellt am {0}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/webhooks/page.tsx:89
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/webhooks/page.tsx:94
|
||||
#~ msgid "Created on <0/>"
|
||||
#~ msgstr "Created on <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/tokens/page.tsx:100
|
||||
msgid "Created on{0}"
|
||||
@@ -1220,7 +1218,7 @@ msgid "Document created"
|
||||
msgstr "Dokument erstellt"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:147
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:59
|
||||
msgid "Document deleted"
|
||||
msgstr "Dokument gelöscht"
|
||||
@@ -1233,7 +1231,7 @@ msgstr "Dokument-Entwurf"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Dokument dupliziert"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:184
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:158
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Dokumentverlauf"
|
||||
@@ -1274,7 +1272,7 @@ msgstr "Dokument erneut gesendet"
|
||||
msgid "Document resealed"
|
||||
msgstr "Dokument wieder versiegelt"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:298
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:276
|
||||
msgid "Document sent"
|
||||
msgstr "Dokument gesendet"
|
||||
|
||||
@@ -1312,11 +1310,11 @@ msgstr "Dokument wird dauerhaft gelöscht"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/nav.tsx:65
|
||||
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:92
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:139
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:113
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:82
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:110
|
||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||
#: apps/web/src/app/not-found.tsx:21
|
||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||
@@ -1335,7 +1333,7 @@ msgid "Documents Viewed"
|
||||
msgstr "Dokumente angesehen"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/reset-password/[token]/page.tsx:40
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:45
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:61
|
||||
msgid "Don't have an account? <0>Sign up</0>"
|
||||
msgstr "Haben Sie kein Konto? <0>Registrieren</0>"
|
||||
|
||||
@@ -1412,7 +1410,7 @@ msgstr "Webhook bearbeiten"
|
||||
#: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153
|
||||
#: apps/web/src/components/forms/forgot-password.tsx:81
|
||||
#: apps/web/src/components/forms/profile.tsx:122
|
||||
#: apps/web/src/components/forms/signin.tsx:338
|
||||
#: apps/web/src/components/forms/signin.tsx:326
|
||||
#: apps/web/src/components/forms/signup.tsx:180
|
||||
msgid "Email"
|
||||
msgstr "E-Mail"
|
||||
@@ -1423,7 +1421,7 @@ msgstr "E-Mail"
|
||||
msgid "Email address"
|
||||
msgstr "E-Mail-Adresse"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:328
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:316
|
||||
msgid "Email Address"
|
||||
msgstr "E-Mail-Adresse"
|
||||
|
||||
@@ -1491,16 +1489,16 @@ msgstr "Geben Sie hier Ihren Text ein"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/admin-actions.tsx:41
|
||||
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:78
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:213
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:247
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:277
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:308
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:198
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:225
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:255
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:286
|
||||
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:57
|
||||
#: apps/web/src/app/(dashboard)/documents/upload-document.tsx:106
|
||||
#: apps/web/src/app/(dashboard)/documents/upload-document.tsx:112
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:165
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:196
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:230
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:152
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:175
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:209
|
||||
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:56
|
||||
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:152
|
||||
@@ -1544,10 +1542,8 @@ msgstr "Zeitüberschreitung überschritten"
|
||||
msgid "Expired"
|
||||
msgstr "Abgelaufen"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/tokens/page.tsx:73
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/tokens/page.tsx:106
|
||||
#~ msgid "Expires on"
|
||||
#~ msgstr "Expires on"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/tokens/page.tsx:71
|
||||
msgid "Expires on {0}"
|
||||
@@ -1560,7 +1556,7 @@ msgstr ">>>>>>> 4ca18b99 (fix: refactor dates)"
|
||||
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/tokens/page.tsx:107
|
||||
msgid "Expires on{0}"
|
||||
msgstr "Läuft ab am{0}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/admin-actions.tsx:42
|
||||
msgid "Failed to reseal document"
|
||||
@@ -1584,7 +1580,7 @@ msgid "File cannot be larger than {APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB"
|
||||
msgstr "Die Datei darf nicht größer als {APP_DOCUMENT_UPLOAD_SIZE_LIMIT} MB sein"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21
|
||||
#: apps/web/src/components/forms/signin.tsx:370
|
||||
#: apps/web/src/components/forms/signin.tsx:358
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Haben Sie Ihr Passwort vergessen?"
|
||||
|
||||
@@ -1593,11 +1589,11 @@ msgstr "Haben Sie Ihr Passwort vergessen?"
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:361
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:241
|
||||
#: apps/web/src/components/forms/profile.tsx:110
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:312
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:300
|
||||
msgid "Full Name"
|
||||
msgstr "Vollständiger Name"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:146
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:132
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:76
|
||||
#: apps/web/src/app/(recipient)/d/[token]/direct-template.tsx:60
|
||||
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:43
|
||||
@@ -1620,7 +1616,7 @@ msgstr "Zurück"
|
||||
msgid "Go back home"
|
||||
msgstr "Zurück nach Hause"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:223
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Zurück nach Hause"
|
||||
@@ -1778,13 +1774,9 @@ msgstr "Es scheint, dass kein Token bereitgestellt wurde. Wenn Sie versuchen, Ih
|
||||
msgid "It seems that there is no token provided. Please check your email and try again."
|
||||
msgstr "Es scheint, dass kein Token bereitgestellt wurde. Bitte überprüfen Sie Ihre E-Mail und versuchen Sie es erneut."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:74
|
||||
msgid "It's currently not your turn to sign. You will receive an email with instructions once it's your turn to sign the document."
|
||||
msgstr "Es ist derzeit nicht deine Reihe zu unterschreiben. Du erhältst eine E-Mail mit Anweisungen, sobald es deine Reihe ist, das Dokument zu unterschreiben."
|
||||
|
||||
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:286
|
||||
msgid "Language"
|
||||
msgstr "Sprache"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/(dashboard)/period-selector/period-selector.tsx:61
|
||||
msgid "Last 14 days"
|
||||
@@ -1864,8 +1856,8 @@ msgid "Loading..."
|
||||
msgstr "Wird geladen..."
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:54
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:75
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:67
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:78
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:72
|
||||
msgid "Login"
|
||||
msgstr "Anmelden"
|
||||
|
||||
@@ -1937,7 +1929,7 @@ msgstr "Verwalten Sie Ihre Passkeys."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Verwalten Sie hier Ihre Seiteneinstellungen"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:120
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Als angesehen markieren"
|
||||
|
||||
@@ -2016,7 +2008,7 @@ msgstr "Meine Vorlagen"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:210
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "Müssen Dokumente signieren?"
|
||||
|
||||
@@ -2039,11 +2031,11 @@ msgstr "Neue Vorlage"
|
||||
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:416
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:295
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:521
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:509
|
||||
msgid "Next"
|
||||
msgstr "Nächster"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:58
|
||||
msgid "Next field"
|
||||
msgstr "Nächstes Feld"
|
||||
|
||||
@@ -2101,10 +2093,6 @@ msgstr "Nicht unterstützt"
|
||||
msgid "Nothing to do"
|
||||
msgstr "Nichts zu tun"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:270
|
||||
msgid "Number"
|
||||
msgstr "Nummer"
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/webhooks/create-webhook-dialog.tsx:128
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "Auf dieser Seite können Sie einen neuen Webhook erstellen."
|
||||
@@ -2150,11 +2138,11 @@ msgstr "Geöffnet"
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:337
|
||||
#: apps/web/src/components/forms/signup.tsx:243
|
||||
#: apps/web/src/components/forms/signup.tsx:267
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:383
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:371
|
||||
msgid "Or"
|
||||
msgstr "Oder"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:390
|
||||
#: apps/web/src/components/forms/signin.tsx:378
|
||||
msgid "Or continue with"
|
||||
msgstr "Oder fahren Sie fort mit"
|
||||
|
||||
@@ -2171,7 +2159,7 @@ msgstr "Besitzer"
|
||||
msgid "Paid"
|
||||
msgstr "Bezahlt"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:435
|
||||
#: apps/web/src/components/forms/signin.tsx:423
|
||||
msgid "Passkey"
|
||||
msgstr "Passkey"
|
||||
|
||||
@@ -2211,9 +2199,9 @@ msgstr "Passkeys werden von diesem Browser nicht unterstützt"
|
||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:70
|
||||
#: apps/web/src/components/forms/password.tsx:123
|
||||
#: apps/web/src/components/forms/reset-password.tsx:110
|
||||
#: apps/web/src/components/forms/signin.tsx:356
|
||||
#: apps/web/src/components/forms/signin.tsx:344
|
||||
#: apps/web/src/components/forms/signup.tsx:196
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:344
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:332
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
@@ -2278,10 +2266,6 @@ msgstr "Wählen Sie eine der folgenden Vereinbarungen aus und beginnen Sie das S
|
||||
msgid "Please check the CSV file and make sure it is according to our format"
|
||||
msgstr "Bitte prüfen Sie die CSV-Datei und stellen Sie sicher, dass sie unserem Format entspricht"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:81
|
||||
msgid "Please check your email for updates."
|
||||
msgstr "Bitte überprüfe deine E-Mail auf Updates."
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/reset-password/[token]/page.tsx:34
|
||||
msgid "Please choose your new password"
|
||||
msgstr "Bitte wählen Sie Ihr neues Passwort"
|
||||
@@ -2294,7 +2278,7 @@ msgstr "Bitte kontaktieren Sie den Support, wenn Sie diese Aktion rückgängig m
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Bitte geben Sie einen aussagekräftigen Namen für Ihr Token ein. Dies wird Ihnen helfen, es später zu identifizieren."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:127
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Bitte als angesehen markieren, um abzuschließen"
|
||||
|
||||
@@ -2404,7 +2388,7 @@ msgstr "Öffentliches Profil"
|
||||
msgid "Public profile URL"
|
||||
msgstr "Öffentlicher Profil-URL"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:450
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:438
|
||||
msgid "Public profile username"
|
||||
msgstr "Öffentlicher Profil-Benutzername"
|
||||
|
||||
@@ -2625,7 +2609,7 @@ msgstr "Sicherheit"
|
||||
msgid "Security activity"
|
||||
msgstr "Sicherheitsaktivität"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:194
|
||||
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:192
|
||||
msgid "Select"
|
||||
msgstr "Auswählen"
|
||||
|
||||
@@ -2729,7 +2713,7 @@ msgstr "Vorlagen in Ihrem Team-Öffentliches Profil anzeigen, damit Ihre Zielgru
|
||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:121
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:259
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -2758,17 +2742,17 @@ msgid "Sign field"
|
||||
msgstr "Unterzeichnen-Feld"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:212
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:362
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:350
|
||||
msgid "Sign Here"
|
||||
msgstr "Hier unterzeichnen"
|
||||
|
||||
#: apps/web/src/app/not-found.tsx:29
|
||||
#: apps/web/src/components/forms/signin.tsx:383
|
||||
#: apps/web/src/components/forms/signin.tsx:510
|
||||
#: apps/web/src/components/forms/signin.tsx:371
|
||||
#: apps/web/src/components/forms/signin.tsx:498
|
||||
msgid "Sign In"
|
||||
msgstr "Einloggen"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:29
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:44
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Melden Sie sich bei Ihrem Konto an"
|
||||
|
||||
@@ -2782,7 +2766,7 @@ msgstr "Ausloggen"
|
||||
msgid "Sign the document to complete the process."
|
||||
msgstr "Unterschreiben Sie das Dokument, um den Vorgang abzuschließen."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:67
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:72
|
||||
msgid "Sign up"
|
||||
msgstr "Registrieren"
|
||||
|
||||
@@ -2791,12 +2775,12 @@ msgid "Sign Up"
|
||||
msgstr "Registrieren"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:257
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:401
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:389
|
||||
msgid "Sign Up with Google"
|
||||
msgstr "Registrieren mit Google"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:281
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:417
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:405
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Registrieren mit OIDC"
|
||||
|
||||
@@ -2822,8 +2806,8 @@ msgstr "Unterschriften erscheinen, sobald das Dokument abgeschlossen ist"
|
||||
msgid "Signed"
|
||||
msgstr "Unterzeichnet"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:383
|
||||
#: apps/web/src/components/forms/signin.tsx:510
|
||||
#: apps/web/src/components/forms/signin.tsx:371
|
||||
#: apps/web/src/components/forms/signin.tsx:498
|
||||
msgid "Signing in..."
|
||||
msgstr "Anmeldung..."
|
||||
|
||||
@@ -2868,7 +2852,7 @@ msgstr "Website Einstellungen"
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:151
|
||||
#: apps/web/src/app/(recipient)/d/[token]/direct-template.tsx:117
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:27
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:38
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:43
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/layout-billing-banner.tsx:53
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:39
|
||||
#: apps/web/src/app/(unauthenticated)/verify-email/[token]/page.tsx:61
|
||||
@@ -3129,7 +3113,7 @@ msgstr "Template has been updated."
|
||||
msgid "Template moved"
|
||||
msgstr "Template moved"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:219
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:198
|
||||
msgid "Template saved"
|
||||
msgstr "Template saved"
|
||||
|
||||
@@ -3145,11 +3129,6 @@ msgstr "Templates"
|
||||
msgid "Templates allow you to quickly generate documents with pre-filled recipients and fields."
|
||||
msgstr "Templates allow you to quickly generate documents with pre-filled recipients and fields."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:256
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:272
|
||||
msgid "Text"
|
||||
msgstr "Text"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/site-settings/banner-form.tsx:166
|
||||
msgid "Text Color"
|
||||
msgstr "Text Color"
|
||||
@@ -3327,11 +3306,11 @@ msgstr "This document has been cancelled by the owner and is no longer available
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "This document has been cancelled by the owner."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:219
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:193
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "This document has been signed by all recipients"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:222
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:196
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "This document is currently a draft and has not been sent"
|
||||
|
||||
@@ -3434,7 +3413,7 @@ msgstr "To enable two-factor authentication, scan the following QR code using yo
|
||||
msgid "To gain access to your account, please confirm your email address by clicking on the confirmation link from your inbox."
|
||||
msgstr "To gain access to your account, please confirm your email address by clicking on the confirmation link from your inbox."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:54
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:57
|
||||
msgid "To mark this document as viewed, you need to be logged in as <0>{0}</0>"
|
||||
msgstr "To mark this document as viewed, you need to be logged in as <0>{0}</0>"
|
||||
|
||||
@@ -3523,7 +3502,7 @@ msgstr "Two factor authentication"
|
||||
msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
|
||||
msgstr "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:448
|
||||
#: apps/web/src/components/forms/signin.tsx:436
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Two-Factor Authentication"
|
||||
|
||||
@@ -3558,7 +3537,7 @@ msgstr "Uh oh! Looks like you're missing a token"
|
||||
|
||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:303
|
||||
msgid "Unable to change the language at this time. Please try again later."
|
||||
msgstr "Derzeit kann die Sprache nicht geändert werden. Bitte versuchen Sie es später erneut."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/forms/2fa/recovery-code-list.tsx:31
|
||||
msgid "Unable to copy recovery code"
|
||||
@@ -3733,12 +3712,12 @@ msgid "Uploaded file not an allowed file type"
|
||||
msgstr "Die hochgeladene Datei ist kein zulässiger Dateityp"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187
|
||||
#: apps/web/src/components/forms/signin.tsx:505
|
||||
#: apps/web/src/components/forms/signin.tsx:493
|
||||
msgid "Use Authenticator"
|
||||
msgstr "Authenticator verwenden"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185
|
||||
#: apps/web/src/components/forms/signin.tsx:503
|
||||
#: apps/web/src/components/forms/signin.tsx:491
|
||||
msgid "Use Backup Code"
|
||||
msgstr "Backup-Code verwenden"
|
||||
|
||||
@@ -3754,7 +3733,7 @@ msgstr "Benutzer"
|
||||
msgid "User ID"
|
||||
msgstr "Benutzer-ID"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:234
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:222
|
||||
msgid "User profiles are here!"
|
||||
msgstr "Benutzerprofile sind hier!"
|
||||
|
||||
@@ -3856,10 +3835,6 @@ msgstr "Warten"
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "Warten auf andere, um zu unterschreiben"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:70
|
||||
msgid "Waiting for Your Turn"
|
||||
msgstr "Warten auf deine Reihe"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:61
|
||||
msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
|
||||
msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüfen Sie Documenso.</0>"
|
||||
@@ -4033,7 +4008,7 @@ msgid "We were unable to disable two-factor authentication for your account. Ple
|
||||
msgstr "Wir konnten die Zwei-Faktor-Authentifizierung für Ihr Konto nicht deaktivieren. Bitte stellen Sie sicher, dass Sie Ihr Passwort und den Backup-Code korrekt eingegeben haben und versuchen Sie es erneut."
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:28
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:39
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:44
|
||||
msgid "We were unable to log you out at this time."
|
||||
msgstr "Wir konnten Sie zurzeit nicht abmelden."
|
||||
|
||||
@@ -4100,14 +4075,10 @@ msgstr "Webhooks"
|
||||
msgid "Weekly"
|
||||
msgstr "Wöchentlich"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:33
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:48
|
||||
msgid "Welcome back, we are lucky to have you."
|
||||
msgstr "Willkommen zurück, wir freuen uns, Sie zu haben."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:88
|
||||
msgid "Were you trying to edit this document instead?"
|
||||
msgstr "Hast du stattdessen versucht, dieses Dokument zu bearbeiten?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:189
|
||||
msgid "When you click continue, you will be prompted to add the first available authenticator on your system."
|
||||
msgstr "Wenn Sie auf Fortfahren klicken, werden Sie aufgefordert, den ersten verfügbaren Authenticator auf Ihrem System hinzuzufügen."
|
||||
@@ -4136,15 +4107,15 @@ msgstr "Jährlich"
|
||||
msgid "You"
|
||||
msgstr "Sie"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, die Genehmigung für \"{truncatedTitle}\" abzuschließen.<0/> Sind Sie sicher?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:82
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" zu unterzeichnen.<0/> Sind Sie sicher?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:74
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "Sie stehen kurz davor, \"{truncatedTitle}\" anzusehen.<0/> Sind Sie sicher?"
|
||||
|
||||
@@ -4326,7 +4297,7 @@ msgstr "Sie müssen mindestens einen anderen Teamkollegen haben, um die Eigentum
|
||||
msgid "You must set a profile URL before enabling your public profile."
|
||||
msgstr "Sie müssen eine Profil-URL festlegen, bevor Sie Ihr öffentliches Profil aktivieren."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:56
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:61
|
||||
msgid "You need to be logged in as <0>{email}</0> to view this page."
|
||||
msgstr "Sie müssen als <0>{email}</0> angemeldet sein, um diese Seite anzuzeigen."
|
||||
|
||||
@@ -4338,7 +4309,7 @@ msgstr "Sie müssen angemeldet sein, um diese Seite anzuzeigen."
|
||||
msgid "You need to setup 2FA to mark this document as viewed."
|
||||
msgstr "Sie müssen 2FA einrichten, um dieses Dokument als angesehen zu markieren."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:283
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:271
|
||||
msgid "You will get notified & be able to set up your documenso public profile when we launch the feature."
|
||||
msgstr "Sie werden benachrichtigt und können Ihr Documenso öffentliches Profil einrichten, wenn wir die Funktion starten."
|
||||
|
||||
@@ -4382,7 +4353,7 @@ msgstr "Ihr Dokument wurde erfolgreich aus der Vorlage erstellt."
|
||||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Ihr Dokument wurde erfolgreich erneut gesendet."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:299
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:277
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Ihr Dokument wurde erfolgreich gesendet."
|
||||
|
||||
@@ -4473,7 +4444,7 @@ msgstr "Ihre Vorlage wurde erfolgreich gelöscht."
|
||||
msgid "Your template will be duplicated."
|
||||
msgstr "Ihre Vorlage wird dupliziert."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:220
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:199
|
||||
msgid "Your templates has been saved successfully."
|
||||
msgstr "Ihre Vorlagen wurden erfolgreich gespeichert."
|
||||
|
||||
|
||||
@@ -55,12 +55,12 @@ msgstr "<0>Require passkey</0> - The recipient must have an account and passkey
|
||||
msgid "Add a document"
|
||||
msgstr "Add a document"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:336
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:305
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:339
|
||||
msgid "Add a URL to redirect the user to once the document is signed"
|
||||
msgstr "Add a URL to redirect the user to once the document is signed"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:248
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:217
|
||||
msgid "Add an external ID to the document. This can be used to identify the document in external systems."
|
||||
msgstr "Add an external ID to the document. This can be used to identify the document in external systems."
|
||||
|
||||
@@ -77,19 +77,19 @@ msgstr "Add another option"
|
||||
msgid "Add another value"
|
||||
msgstr "Add another value"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:662
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:459
|
||||
msgid "Add myself"
|
||||
msgstr "Add myself"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:450
|
||||
msgid "Add Myself"
|
||||
msgstr "Add Myself"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:436
|
||||
msgid "Add Placeholder Recipient"
|
||||
msgstr "Add Placeholder Recipient"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:651
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:448
|
||||
msgid "Add Signer"
|
||||
msgstr "Add Signer"
|
||||
|
||||
@@ -105,12 +105,12 @@ msgstr "Add text to the field"
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:230
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:199
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:238
|
||||
msgid "Advanced Options"
|
||||
msgstr "Advanced Options"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:565
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:510
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:402
|
||||
msgid "Advanced settings"
|
||||
msgstr "Advanced settings"
|
||||
@@ -148,13 +148,9 @@ msgstr "Blue"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:193
|
||||
msgid "Cannot remove signer"
|
||||
msgstr "Cannot remove signer"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:221
|
||||
#~ msgid "Cannot update signer because they have already signed a field"
|
||||
#~ msgstr "Cannot update signer because they have already signed a field"
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:164
|
||||
#~ msgid "Cannot remove signer"
|
||||
#~ msgstr "Cannot remove signer"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:17
|
||||
msgid "Cc"
|
||||
@@ -173,7 +169,7 @@ msgstr "CC'd"
|
||||
msgid "Character Limit"
|
||||
msgstr "Character Limit"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:993
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:932
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:788
|
||||
msgid "Checkbox"
|
||||
msgstr "Checkbox"
|
||||
@@ -202,7 +198,7 @@ msgstr "Close"
|
||||
msgid "Configure Direct Recipient"
|
||||
msgstr "Configure Direct Recipient"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:566
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:511
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:403
|
||||
msgid "Configure the {0} field"
|
||||
msgstr "Configure the {0} field"
|
||||
@@ -219,22 +215,22 @@ msgstr "Copied to clipboard"
|
||||
msgid "Custom Text"
|
||||
msgstr "Custom Text"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:889
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:828
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:684
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:271
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:240
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:279
|
||||
msgid "Date Format"
|
||||
msgstr "Date Format"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:393
|
||||
msgid "Direct link receiver"
|
||||
msgstr "Direct link receiver"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:62
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:174
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:166
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:151
|
||||
msgid "Document access"
|
||||
msgstr "Document access"
|
||||
@@ -251,7 +247,7 @@ msgstr "Download"
|
||||
msgid "Drag & drop your PDF here."
|
||||
msgstr "Drag & drop your PDF here."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1019
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:958
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:814
|
||||
msgid "Dropdown"
|
||||
msgstr "Dropdown"
|
||||
@@ -260,12 +256,13 @@ msgstr "Dropdown"
|
||||
msgid "Dropdown options"
|
||||
msgstr "Dropdown options"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:837
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:776
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:272
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:500
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:330
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:337
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:632
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:296
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:303
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
@@ -273,19 +270,10 @@ msgstr "Email"
|
||||
msgid "Email Options"
|
||||
msgstr "Email Options"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1082
|
||||
msgid "Empty field"
|
||||
msgstr "Empty field"
|
||||
|
||||
#: packages/lib/constants/template.ts:8
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Enable Direct Link Signing"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:401
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
|
||||
msgid "Enable signing order"
|
||||
msgstr "Enable signing order"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:84
|
||||
msgid "Enter password"
|
||||
msgstr "Enter password"
|
||||
@@ -294,7 +282,7 @@ msgstr "Enter password"
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:241
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:210
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:249
|
||||
msgid "External ID"
|
||||
msgstr "External ID"
|
||||
@@ -383,13 +371,12 @@ msgstr "Message <0>(Optional)</0>"
|
||||
msgid "Min"
|
||||
msgstr "Min"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:863
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:802
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:298
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:535
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:541
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:364
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:658
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:327
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:333
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
@@ -405,12 +392,12 @@ msgstr "Needs to sign"
|
||||
msgid "Needs to view"
|
||||
msgstr "Needs to view"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:674
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:613
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:497
|
||||
msgid "No recipient matching this description was found."
|
||||
msgstr "No recipient matching this description was found."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:690
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:629
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:513
|
||||
msgid "No recipients with this role"
|
||||
msgstr "No recipients with this role"
|
||||
@@ -435,7 +422,7 @@ msgstr "No signature field found"
|
||||
msgid "No value found."
|
||||
msgstr "No value found."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:941
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:880
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:736
|
||||
msgid "Number"
|
||||
msgstr "Number"
|
||||
@@ -470,7 +457,7 @@ msgstr "Pick a number"
|
||||
msgid "Placeholder"
|
||||
msgstr "Placeholder"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:967
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:906
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:762
|
||||
msgid "Radio"
|
||||
msgstr "Radio"
|
||||
@@ -492,7 +479,7 @@ msgid "Receives copy"
|
||||
msgstr "Receives copy"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:215
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:184
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:169
|
||||
msgid "Recipient action authentication"
|
||||
msgstr "Recipient action authentication"
|
||||
@@ -501,12 +488,12 @@ msgstr "Recipient action authentication"
|
||||
msgid "Red"
|
||||
msgstr "Red"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:329
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:298
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:332
|
||||
msgid "Redirect URL"
|
||||
msgstr "Redirect URL"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1069
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:996
|
||||
msgid "Remove"
|
||||
msgstr "Remove"
|
||||
|
||||
@@ -568,8 +555,8 @@ msgstr "Share Signature Card"
|
||||
msgid "Share the Link"
|
||||
msgstr "Share the Link"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:680
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:477
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:468
|
||||
msgid "Show advanced settings"
|
||||
msgstr "Show advanced settings"
|
||||
|
||||
@@ -577,7 +564,7 @@ msgstr "Show advanced settings"
|
||||
msgid "Sign"
|
||||
msgstr "Sign"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:785
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:724
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:323
|
||||
#: packages/ui/primitives/document-flow/field-icon.tsx:52
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:580
|
||||
@@ -625,7 +612,7 @@ msgstr "Submit"
|
||||
msgid "Template title"
|
||||
msgstr "Template title"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:915
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:854
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:710
|
||||
msgid "Text"
|
||||
msgstr "Text"
|
||||
@@ -686,7 +673,7 @@ msgstr "The signer's name"
|
||||
msgid "This can be overriden by setting the authentication requirements directly on each recipient in the next step."
|
||||
msgstr "This can be overriden by setting the authentication requirements directly on each recipient in the next step."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:746
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:685
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
msgstr "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
|
||||
@@ -694,36 +681,28 @@ msgstr "This document has already been sent to this recipient. You can no longer
|
||||
msgid "This document is password protected. Please enter the password to view the document."
|
||||
msgstr "This document is password protected. Please enter the password to view the document."
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:396
|
||||
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
|
||||
msgstr "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1050
|
||||
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
|
||||
msgstr "This recipient can no longer be modified as they have signed a field, or completed the document."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:165
|
||||
#~ msgid "This signer has already received the document."
|
||||
#~ msgstr "This signer has already received the document."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:194
|
||||
msgid "This signer has already signed the document."
|
||||
msgstr "This signer has already signed the document."
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
|
||||
msgid "This will override any global settings."
|
||||
msgstr "This will override any global settings."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:305
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:274
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:309
|
||||
msgid "Time Zone"
|
||||
msgstr "Time Zone"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:153
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:145
|
||||
msgid "Title"
|
||||
msgstr "Title"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1033
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:971
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:828
|
||||
msgid "To proceed further, please set at least one value for the {0} field."
|
||||
msgstr "To proceed further, please set at least one value for the {0} field."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -218,7 +218,6 @@ msgstr "From the blog"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:9
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:17
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:33
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:41
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:49
|
||||
@@ -381,8 +380,8 @@ msgid "Our self-hosted option is great for small teams and individuals who need
|
||||
msgstr "Our self-hosted option is great for small teams and individuals who need a simple solution. You can use our docker based setup to get started in minutes. Take control with full customizability and data ownership."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#~ msgid "Part-Time"
|
||||
#~ msgstr "Part-Time"
|
||||
msgid "Part-Time"
|
||||
msgstr "Part-Time"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:151
|
||||
msgid "Premium Profile Name"
|
||||
@@ -610,6 +609,6 @@ msgstr "Yes! Documenso is offered under the GNU AGPL V3 open source license. Thi
|
||||
msgid "You can self-host Documenso for free or use our ready-to-use hosted version. The hosted version comes with additional support, painless scalability and more. Early adopters will get access to all features we build this year, for no additional cost! Forever! Yes, that includes multiple users per account later. If you want Documenso for your enterprise, we are happy to talk about your needs."
|
||||
msgstr "You can self-host Documenso for free or use our ready-to-use hosted version. The hosted version comes with additional support, painless scalability and more. Early adopters will get access to all features we build this year, for no additional cost! Forever! Yes, that includes multiple users per account later. If you want Documenso for your enterprise, we are happy to talk about your needs."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:265
|
||||
msgid "Your browser does not support the video tag."
|
||||
msgstr "Your browser does not support the video tag."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -21,15 +21,15 @@ msgstr "\"{0}\" will appear on the document as it has a timezone of \"{timezone}
|
||||
msgid "\"{documentTitle}\" has been successfully deleted"
|
||||
msgstr "\"{documentTitle}\" has been successfully deleted"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:78
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:76
|
||||
msgid "({0}) has invited you to approve this document"
|
||||
msgstr "({0}) has invited you to approve this document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:75
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:73
|
||||
msgid "({0}) has invited you to sign this document"
|
||||
msgstr "({0}) has invited you to sign this document"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:72
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:70
|
||||
msgid "({0}) has invited you to view this document"
|
||||
msgstr "({0}) has invited you to view this document"
|
||||
|
||||
@@ -55,11 +55,11 @@ msgstr "{0, plural, one {# Seat} other {# Seats}}"
|
||||
msgid "{0, plural, one {<0>You have <1>1</1> pending team invitation</0>} other {<2>You have <3>#</3> pending team invitations</2>}}"
|
||||
msgstr "{0, plural, one {<0>You have <1>1</1> pending team invitation</0>} other {<2>You have <3>#</3> pending team invitations</2>}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:102
|
||||
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
msgstr "{0, plural, one {1 Recipient} other {# Recipients}}"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:230
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:204
|
||||
msgid "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
msgstr "{0, plural, one {Waiting on 1 recipient} other {Waiting on # recipients}}"
|
||||
|
||||
@@ -79,7 +79,7 @@ msgstr "{0} document"
|
||||
msgid "{0} of {1} documents remaining this month."
|
||||
msgstr "{0} of {1} documents remaining this month."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:165
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:139
|
||||
msgid "{0} Recipient(s)"
|
||||
msgstr "{0} Recipient(s)"
|
||||
|
||||
@@ -215,7 +215,7 @@ msgstr "Active Subscriptions"
|
||||
msgid "Add"
|
||||
msgstr "Add"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:157
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:143
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:87
|
||||
msgid "Add all relevant fields for each recipient."
|
||||
msgstr "Add all relevant fields for each recipient."
|
||||
@@ -236,7 +236,7 @@ msgstr "Add an authenticator to serve as a secondary authentication method when
|
||||
msgid "Add email"
|
||||
msgstr "Add email"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:156
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:142
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:86
|
||||
msgid "Add Fields"
|
||||
msgstr "Add Fields"
|
||||
@@ -246,8 +246,8 @@ msgid "Add more"
|
||||
msgstr "Add more"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:270
|
||||
#~ msgid "Add number"
|
||||
#~ msgstr "Add number"
|
||||
msgid "Add number"
|
||||
msgstr "Add number"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:146
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:154
|
||||
@@ -258,11 +258,11 @@ msgstr "Add passkey"
|
||||
msgid "Add Placeholders"
|
||||
msgstr "Add Placeholders"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:151
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:137
|
||||
msgid "Add Signers"
|
||||
msgstr "Add Signers"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:161
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:147
|
||||
msgid "Add Subject"
|
||||
msgstr "Add Subject"
|
||||
|
||||
@@ -271,14 +271,14 @@ msgid "Add team email"
|
||||
msgstr "Add team email"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:256
|
||||
#~ msgid "Add text"
|
||||
#~ msgstr "Add text"
|
||||
msgid "Add text"
|
||||
msgstr "Add text"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:272
|
||||
#~ msgid "Add Text"
|
||||
#~ msgstr "Add Text"
|
||||
msgid "Add Text"
|
||||
msgstr "Add Text"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:152
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:138
|
||||
msgid "Add the people who will sign the document."
|
||||
msgstr "Add the people who will sign the document."
|
||||
|
||||
@@ -286,7 +286,7 @@ msgstr "Add the people who will sign the document."
|
||||
msgid "Add the recipients to create the document with"
|
||||
msgstr "Add the recipients to create the document with"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:162
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:148
|
||||
msgid "Add the subject and message you wish to send to signers."
|
||||
msgstr "Add the subject and message you wish to send to signers."
|
||||
|
||||
@@ -334,7 +334,7 @@ msgstr "All Time"
|
||||
msgid "Allows authenticating using biometrics, password managers, hardware keys, etc."
|
||||
msgstr "Allows authenticating using biometrics, password managers, hardware keys, etc."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:423
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:411
|
||||
msgid "Already have an account? <0>Sign in instead</0>"
|
||||
msgstr "Already have an account? <0>Sign in instead</0>"
|
||||
|
||||
@@ -365,13 +365,13 @@ msgstr "An email requesting the transfer of this team has been sent."
|
||||
msgid "An error occurred"
|
||||
msgstr "An error occurred"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:248
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:197
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:231
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:226
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:176
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:210
|
||||
msgid "An error occurred while adding signers."
|
||||
msgstr "An error occurred while adding signers."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:278
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:256
|
||||
msgid "An error occurred while adding the fields."
|
||||
msgstr "An error occurred while adding the fields."
|
||||
|
||||
@@ -429,7 +429,7 @@ msgstr "An error occurred while removing the signature."
|
||||
msgid "An error occurred while removing the text."
|
||||
msgstr "An error occurred while removing the text."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:309
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:287
|
||||
msgid "An error occurred while sending the document."
|
||||
msgstr "An error occurred while sending the document."
|
||||
|
||||
@@ -453,8 +453,8 @@ msgstr "An error occurred while signing the document."
|
||||
msgid "An error occurred while trying to create a checkout session."
|
||||
msgstr "An error occurred while trying to create a checkout session."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:214
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:166
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:199
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:153
|
||||
msgid "An error occurred while updating the document settings."
|
||||
msgstr "An error occurred while updating the document settings."
|
||||
|
||||
@@ -534,7 +534,7 @@ msgstr "App Version"
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-button.tsx:89
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:120
|
||||
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:144
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:125
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:122
|
||||
msgid "Approve"
|
||||
msgstr "Approve"
|
||||
|
||||
@@ -573,7 +573,7 @@ msgid "Audit Log"
|
||||
msgstr "Audit Log"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:41
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:52
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:57
|
||||
msgid "Authentication required"
|
||||
msgstr "Authentication required"
|
||||
|
||||
@@ -591,7 +591,7 @@ msgstr "Awaiting email confirmation"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:369
|
||||
#: apps/web/src/components/(dashboard)/settings/layout/activity-back.tsx:20
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:509
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:497
|
||||
msgid "Back"
|
||||
msgstr "Back"
|
||||
|
||||
@@ -604,7 +604,7 @@ msgid "Background Color"
|
||||
msgstr "Background Color"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167
|
||||
#: apps/web/src/components/forms/signin.tsx:485
|
||||
#: apps/web/src/components/forms/signin.tsx:473
|
||||
msgid "Backup Code"
|
||||
msgstr "Backup Code"
|
||||
|
||||
@@ -616,7 +616,7 @@ msgstr "Backup codes"
|
||||
msgid "Banner Updated"
|
||||
msgstr "Banner Updated"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:472
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:460
|
||||
msgid "Basic details"
|
||||
msgstr "Basic details"
|
||||
|
||||
@@ -657,13 +657,13 @@ msgstr "By enabling 2FA, you will be required to enter a code from your authenti
|
||||
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:119
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:470
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:178
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:71
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:74
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-passkey.tsx:164
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-passkey.tsx:189
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:150
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:143
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:327
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:110
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:250
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:333
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
|
||||
@@ -715,7 +715,7 @@ msgstr "Choose..."
|
||||
msgid "Claim account"
|
||||
msgstr "Claim account"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:481
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:469
|
||||
msgid "Claim username"
|
||||
msgstr "Claim username"
|
||||
|
||||
@@ -723,7 +723,7 @@ msgstr "Claim username"
|
||||
msgid "Claim your profile later"
|
||||
msgstr "Claim your profile later"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:279
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:267
|
||||
msgid "Claim your username now"
|
||||
msgstr "Claim your username now"
|
||||
|
||||
@@ -747,7 +747,7 @@ msgid "Click to copy signing link for sending to recipient"
|
||||
msgstr "Click to copy signing link for sending to recipient"
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:175
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:114
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:107
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:435
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:314
|
||||
msgid "Click to insert field"
|
||||
@@ -765,22 +765,22 @@ msgstr "Click to insert field"
|
||||
msgid "Close"
|
||||
msgstr "Close"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:58
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:425
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:304
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:534
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:522
|
||||
msgid "Complete"
|
||||
msgstr "Complete"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:70
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:67
|
||||
msgid "Complete Approval"
|
||||
msgstr "Complete Approval"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:69
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:66
|
||||
msgid "Complete Signing"
|
||||
msgstr "Complete Signing"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:68
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:65
|
||||
msgid "Complete Viewing"
|
||||
msgstr "Complete Viewing"
|
||||
|
||||
@@ -797,7 +797,7 @@ msgstr "Completed documents"
|
||||
msgid "Completed Documents"
|
||||
msgstr "Completed Documents"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:147
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:133
|
||||
msgid "Configure general settings for the document."
|
||||
msgstr "Configure general settings for the document."
|
||||
|
||||
@@ -882,7 +882,7 @@ msgstr "Copy token"
|
||||
msgid "Create"
|
||||
msgstr "Create"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:264
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:252
|
||||
msgid "Create a new account"
|
||||
msgstr "Create a new account"
|
||||
|
||||
@@ -947,11 +947,11 @@ msgstr "Create webhook"
|
||||
msgid "Create Webhook"
|
||||
msgstr "Create Webhook"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:215
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:214
|
||||
msgid "Create your account and start using state-of-the-art document signing."
|
||||
msgstr "Create your account and start using state-of-the-art document signing."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:268
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:256
|
||||
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
|
||||
msgstr "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
|
||||
|
||||
@@ -1215,7 +1215,7 @@ msgid "Document created"
|
||||
msgstr "Document created"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/super-delete-document-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:173
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:147
|
||||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:59
|
||||
msgid "Document deleted"
|
||||
msgstr "Document deleted"
|
||||
@@ -1228,7 +1228,7 @@ msgstr "Document draft"
|
||||
msgid "Document Duplicated"
|
||||
msgstr "Document Duplicated"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:184
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:158
|
||||
#: apps/web/src/components/document/document-history-sheet.tsx:104
|
||||
msgid "Document history"
|
||||
msgstr "Document history"
|
||||
@@ -1269,7 +1269,7 @@ msgstr "Document re-sent"
|
||||
msgid "Document resealed"
|
||||
msgstr "Document resealed"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:298
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:276
|
||||
msgid "Document sent"
|
||||
msgstr "Document sent"
|
||||
|
||||
@@ -1307,11 +1307,11 @@ msgstr "Document will be permanently deleted"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/nav.tsx:65
|
||||
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:92
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:139
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:109
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:113
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:82
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/sent/page.tsx:15
|
||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:119
|
||||
#: apps/web/src/app/(dashboard)/documents/documents-page-view.tsx:110
|
||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:166
|
||||
#: apps/web/src/app/not-found.tsx:21
|
||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:205
|
||||
@@ -1330,7 +1330,7 @@ msgid "Documents Viewed"
|
||||
msgstr "Documents Viewed"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/reset-password/[token]/page.tsx:40
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:45
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:61
|
||||
msgid "Don't have an account? <0>Sign up</0>"
|
||||
msgstr "Don't have an account? <0>Sign up</0>"
|
||||
|
||||
@@ -1407,7 +1407,7 @@ msgstr "Edit webhook"
|
||||
#: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153
|
||||
#: apps/web/src/components/forms/forgot-password.tsx:81
|
||||
#: apps/web/src/components/forms/profile.tsx:122
|
||||
#: apps/web/src/components/forms/signin.tsx:338
|
||||
#: apps/web/src/components/forms/signin.tsx:326
|
||||
#: apps/web/src/components/forms/signup.tsx:180
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
@@ -1418,7 +1418,7 @@ msgstr "Email"
|
||||
msgid "Email address"
|
||||
msgstr "Email address"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:328
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:316
|
||||
msgid "Email Address"
|
||||
msgstr "Email Address"
|
||||
|
||||
@@ -1486,16 +1486,16 @@ msgstr "Enter your text here"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/documents/[id]/admin-actions.tsx:41
|
||||
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:78
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:213
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:247
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:277
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:308
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:198
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:225
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:255
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:286
|
||||
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:57
|
||||
#: apps/web/src/app/(dashboard)/documents/upload-document.tsx:106
|
||||
#: apps/web/src/app/(dashboard)/documents/upload-document.tsx:112
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:165
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:196
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:230
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:152
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:175
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:209
|
||||
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:51
|
||||
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:56
|
||||
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:152
|
||||
@@ -1579,7 +1579,7 @@ msgid "File cannot be larger than {APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB"
|
||||
msgstr "File cannot be larger than {APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21
|
||||
#: apps/web/src/components/forms/signin.tsx:370
|
||||
#: apps/web/src/components/forms/signin.tsx:358
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Forgot your password?"
|
||||
|
||||
@@ -1588,11 +1588,11 @@ msgstr "Forgot your password?"
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:361
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:241
|
||||
#: apps/web/src/components/forms/profile.tsx:110
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:312
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:300
|
||||
msgid "Full Name"
|
||||
msgstr "Full Name"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:146
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:132
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:76
|
||||
#: apps/web/src/app/(recipient)/d/[token]/direct-template.tsx:60
|
||||
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:43
|
||||
@@ -1615,7 +1615,7 @@ msgstr "Go Back"
|
||||
msgid "Go back home"
|
||||
msgstr "Go back home"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:226
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:223
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:57
|
||||
msgid "Go Back Home"
|
||||
msgstr "Go Back Home"
|
||||
@@ -1773,10 +1773,6 @@ msgstr "It seems that there is no token provided, if you are trying to verify yo
|
||||
msgid "It seems that there is no token provided. Please check your email and try again."
|
||||
msgstr "It seems that there is no token provided. Please check your email and try again."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:74
|
||||
msgid "It's currently not your turn to sign. You will receive an email with instructions once it's your turn to sign the document."
|
||||
msgstr "It's currently not your turn to sign. You will receive an email with instructions once it's your turn to sign the document."
|
||||
|
||||
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:286
|
||||
msgid "Language"
|
||||
msgstr "Language"
|
||||
@@ -1859,8 +1855,8 @@ msgid "Loading..."
|
||||
msgstr "Loading..."
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:54
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:75
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:67
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:78
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:72
|
||||
msgid "Login"
|
||||
msgstr "Login"
|
||||
|
||||
@@ -1932,7 +1928,7 @@ msgstr "Manage your passkeys."
|
||||
msgid "Manage your site settings here"
|
||||
msgstr "Manage your site settings here"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:123
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:120
|
||||
msgid "Mark as Viewed"
|
||||
msgstr "Mark as Viewed"
|
||||
|
||||
@@ -2011,7 +2007,7 @@ msgstr "My templates"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:211
|
||||
#: apps/web/src/app/(signing)/sign/[token]/complete/page.tsx:210
|
||||
msgid "Need to sign documents?"
|
||||
msgstr "Need to sign documents?"
|
||||
|
||||
@@ -2034,11 +2030,11 @@ msgstr "New Template"
|
||||
|
||||
#: apps/web/src/app/embed/direct/[[...url]]/client.tsx:416
|
||||
#: apps/web/src/app/embed/sign/[[...url]]/client.tsx:295
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:521
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:509
|
||||
msgid "Next"
|
||||
msgstr "Next"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:61
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:58
|
||||
msgid "Next field"
|
||||
msgstr "Next field"
|
||||
|
||||
@@ -2096,10 +2092,6 @@ msgstr "Not supported"
|
||||
msgid "Nothing to do"
|
||||
msgstr "Nothing to do"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:270
|
||||
msgid "Number"
|
||||
msgstr "Number"
|
||||
|
||||
#: apps/web/src/components/(dashboard)/settings/webhooks/create-webhook-dialog.tsx:128
|
||||
msgid "On this page, you can create a new webhook."
|
||||
msgstr "On this page, you can create a new webhook."
|
||||
@@ -2145,11 +2137,11 @@ msgstr "Opened"
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:337
|
||||
#: apps/web/src/components/forms/signup.tsx:243
|
||||
#: apps/web/src/components/forms/signup.tsx:267
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:383
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:371
|
||||
msgid "Or"
|
||||
msgstr "Or"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:390
|
||||
#: apps/web/src/components/forms/signin.tsx:378
|
||||
msgid "Or continue with"
|
||||
msgstr "Or continue with"
|
||||
|
||||
@@ -2166,7 +2158,7 @@ msgstr "Owner"
|
||||
msgid "Paid"
|
||||
msgstr "Paid"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:435
|
||||
#: apps/web/src/components/forms/signin.tsx:423
|
||||
msgid "Passkey"
|
||||
msgstr "Passkey"
|
||||
|
||||
@@ -2206,9 +2198,9 @@ msgstr "Passkeys are not supported on this browser"
|
||||
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:70
|
||||
#: apps/web/src/components/forms/password.tsx:123
|
||||
#: apps/web/src/components/forms/reset-password.tsx:110
|
||||
#: apps/web/src/components/forms/signin.tsx:356
|
||||
#: apps/web/src/components/forms/signin.tsx:344
|
||||
#: apps/web/src/components/forms/signup.tsx:196
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:344
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:332
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
@@ -2273,10 +2265,6 @@ msgstr "Pick any of the following agreements below and start signing to get star
|
||||
msgid "Please check the CSV file and make sure it is according to our format"
|
||||
msgstr "Please check the CSV file and make sure it is according to our format"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:81
|
||||
msgid "Please check your email for updates."
|
||||
msgstr "Please check your email for updates."
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/reset-password/[token]/page.tsx:34
|
||||
msgid "Please choose your new password"
|
||||
msgstr "Please choose your new password"
|
||||
@@ -2289,7 +2277,7 @@ msgstr "Please contact support if you would like to revert this action."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:134
|
||||
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:127
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Please mark as viewed to complete"
|
||||
|
||||
@@ -2399,7 +2387,7 @@ msgstr "Public Profile"
|
||||
msgid "Public profile URL"
|
||||
msgstr "Public profile URL"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:450
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:438
|
||||
msgid "Public profile username"
|
||||
msgstr "Public profile username"
|
||||
|
||||
@@ -2620,7 +2608,7 @@ msgstr "Security"
|
||||
msgid "Security activity"
|
||||
msgstr "Security activity"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:194
|
||||
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:192
|
||||
msgid "Select"
|
||||
msgstr "Select"
|
||||
|
||||
@@ -2724,7 +2712,7 @@ msgstr "Show templates in your team public profile for your audience to sign and
|
||||
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
|
||||
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:121
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:259
|
||||
#: apps/web/src/components/ui/user-profile-skeleton.tsx:75
|
||||
#: apps/web/src/components/ui/user-profile-timur.tsx:81
|
||||
@@ -2753,17 +2741,17 @@ msgid "Sign field"
|
||||
msgstr "Sign field"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:212
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:362
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:350
|
||||
msgid "Sign Here"
|
||||
msgstr "Sign Here"
|
||||
|
||||
#: apps/web/src/app/not-found.tsx:29
|
||||
#: apps/web/src/components/forms/signin.tsx:383
|
||||
#: apps/web/src/components/forms/signin.tsx:510
|
||||
#: apps/web/src/components/forms/signin.tsx:371
|
||||
#: apps/web/src/components/forms/signin.tsx:498
|
||||
msgid "Sign In"
|
||||
msgstr "Sign In"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:29
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:44
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Sign in to your account"
|
||||
|
||||
@@ -2777,7 +2765,7 @@ msgstr "Sign Out"
|
||||
msgid "Sign the document to complete the process."
|
||||
msgstr "Sign the document to complete the process."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:67
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:72
|
||||
msgid "Sign up"
|
||||
msgstr "Sign up"
|
||||
|
||||
@@ -2786,12 +2774,12 @@ msgid "Sign Up"
|
||||
msgstr "Sign Up"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:257
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:401
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:389
|
||||
msgid "Sign Up with Google"
|
||||
msgstr "Sign Up with Google"
|
||||
|
||||
#: apps/web/src/components/forms/signup.tsx:281
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:417
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:405
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Sign Up with OIDC"
|
||||
|
||||
@@ -2817,8 +2805,8 @@ msgstr "Signatures will appear once the document has been completed"
|
||||
msgid "Signed"
|
||||
msgstr "Signed"
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:383
|
||||
#: apps/web/src/components/forms/signin.tsx:510
|
||||
#: apps/web/src/components/forms/signin.tsx:371
|
||||
#: apps/web/src/components/forms/signin.tsx:498
|
||||
msgid "Signing in..."
|
||||
msgstr "Signing in..."
|
||||
|
||||
@@ -2863,7 +2851,7 @@ msgstr "Site Settings"
|
||||
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:151
|
||||
#: apps/web/src/app/(recipient)/d/[token]/direct-template.tsx:117
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:27
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:38
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:43
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/layout-billing-banner.tsx:53
|
||||
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:39
|
||||
#: apps/web/src/app/(unauthenticated)/verify-email/[token]/page.tsx:61
|
||||
@@ -3124,7 +3112,7 @@ msgstr "Template has been updated."
|
||||
msgid "Template moved"
|
||||
msgstr "Template moved"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:219
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:198
|
||||
msgid "Template saved"
|
||||
msgstr "Template saved"
|
||||
|
||||
@@ -3140,11 +3128,6 @@ msgstr "Templates"
|
||||
msgid "Templates allow you to quickly generate documents with pre-filled recipients and fields."
|
||||
msgstr "Templates allow you to quickly generate documents with pre-filled recipients and fields."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:256
|
||||
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:272
|
||||
msgid "Text"
|
||||
msgstr "Text"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/admin/site-settings/banner-form.tsx:166
|
||||
msgid "Text Color"
|
||||
msgstr "Text Color"
|
||||
@@ -3322,11 +3305,11 @@ msgstr "This document has been cancelled by the owner and is no longer available
|
||||
msgid "This document has been cancelled by the owner."
|
||||
msgstr "This document has been cancelled by the owner."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:219
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:193
|
||||
msgid "This document has been signed by all recipients"
|
||||
msgstr "This document has been signed by all recipients"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:222
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:196
|
||||
msgid "This document is currently a draft and has not been sent"
|
||||
msgstr "This document is currently a draft and has not been sent"
|
||||
|
||||
@@ -3429,7 +3412,7 @@ msgstr "To enable two-factor authentication, scan the following QR code using yo
|
||||
msgid "To gain access to your account, please confirm your email address by clicking on the confirmation link from your inbox."
|
||||
msgstr "To gain access to your account, please confirm your email address by clicking on the confirmation link from your inbox."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:54
|
||||
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:57
|
||||
msgid "To mark this document as viewed, you need to be logged in as <0>{0}</0>"
|
||||
msgstr "To mark this document as viewed, you need to be logged in as <0>{0}</0>"
|
||||
|
||||
@@ -3518,7 +3501,7 @@ msgstr "Two factor authentication"
|
||||
msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
|
||||
msgstr "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
|
||||
|
||||
#: apps/web/src/components/forms/signin.tsx:448
|
||||
#: apps/web/src/components/forms/signin.tsx:436
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Two-Factor Authentication"
|
||||
|
||||
@@ -3728,12 +3711,12 @@ msgid "Uploaded file not an allowed file type"
|
||||
msgstr "Uploaded file not an allowed file type"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187
|
||||
#: apps/web/src/components/forms/signin.tsx:505
|
||||
#: apps/web/src/components/forms/signin.tsx:493
|
||||
msgid "Use Authenticator"
|
||||
msgstr "Use Authenticator"
|
||||
|
||||
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185
|
||||
#: apps/web/src/components/forms/signin.tsx:503
|
||||
#: apps/web/src/components/forms/signin.tsx:491
|
||||
msgid "Use Backup Code"
|
||||
msgstr "Use Backup Code"
|
||||
|
||||
@@ -3749,7 +3732,7 @@ msgstr "User"
|
||||
msgid "User ID"
|
||||
msgstr "User ID"
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:234
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:222
|
||||
msgid "User profiles are here!"
|
||||
msgstr "User profiles are here!"
|
||||
|
||||
@@ -3851,10 +3834,6 @@ msgstr "Waiting"
|
||||
msgid "Waiting for others to sign"
|
||||
msgstr "Waiting for others to sign"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:70
|
||||
msgid "Waiting for Your Turn"
|
||||
msgstr "Waiting for Your Turn"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:61
|
||||
msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
|
||||
msgstr "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
|
||||
@@ -4028,7 +4007,7 @@ msgid "We were unable to disable two-factor authentication for your account. Ple
|
||||
msgstr "We were unable to disable two-factor authentication for your account. Please ensure that you have entered your password and backup code correctly and try again."
|
||||
|
||||
#: apps/web/src/app/(recipient)/d/[token]/signing-auth-page.tsx:28
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:39
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:44
|
||||
msgid "We were unable to log you out at this time."
|
||||
msgstr "We were unable to log you out at this time."
|
||||
|
||||
@@ -4095,14 +4074,10 @@ msgstr "Webhooks"
|
||||
msgid "Weekly"
|
||||
msgstr "Weekly"
|
||||
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:33
|
||||
#: apps/web/src/app/(unauthenticated)/signin/page.tsx:48
|
||||
msgid "Welcome back, we are lucky to have you."
|
||||
msgstr "Welcome back, we are lucky to have you."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:88
|
||||
msgid "Were you trying to edit this document instead?"
|
||||
msgstr "Were you trying to edit this document instead?"
|
||||
|
||||
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:189
|
||||
msgid "When you click continue, you will be prompted to add the first available authenticator on your system."
|
||||
msgstr "When you click continue, you will be prompted to add the first available authenticator on your system."
|
||||
@@ -4131,15 +4106,15 @@ msgstr "Yearly"
|
||||
msgid "You"
|
||||
msgstr "You"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:93
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:90
|
||||
msgid "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete approving \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:85
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:82
|
||||
msgid "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete signing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:77
|
||||
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:74
|
||||
msgid "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
msgstr "You are about to complete viewing \"{truncatedTitle}\".<0/> Are you sure?"
|
||||
|
||||
@@ -4321,7 +4296,7 @@ msgstr "You must have at least one other team member to transfer ownership."
|
||||
msgid "You must set a profile URL before enabling your public profile."
|
||||
msgstr "You must set a profile URL before enabling your public profile."
|
||||
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:56
|
||||
#: apps/web/src/app/(signing)/sign/[token]/signing-auth-page.tsx:61
|
||||
msgid "You need to be logged in as <0>{email}</0> to view this page."
|
||||
msgstr "You need to be logged in as <0>{email}</0> to view this page."
|
||||
|
||||
@@ -4333,7 +4308,7 @@ msgstr "You need to be logged in to view this page."
|
||||
msgid "You need to setup 2FA to mark this document as viewed."
|
||||
msgstr "You need to setup 2FA to mark this document as viewed."
|
||||
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:283
|
||||
#: apps/web/src/components/forms/v2/signup.tsx:271
|
||||
msgid "You will get notified & be able to set up your documenso public profile when we launch the feature."
|
||||
msgstr "You will get notified & be able to set up your documenso public profile when we launch the feature."
|
||||
|
||||
@@ -4377,7 +4352,7 @@ msgstr "Your document has been created from the template successfully."
|
||||
msgid "Your document has been re-sent successfully."
|
||||
msgstr "Your document has been re-sent successfully."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:299
|
||||
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:277
|
||||
msgid "Your document has been sent successfully."
|
||||
msgstr "Your document has been sent successfully."
|
||||
|
||||
@@ -4468,7 +4443,7 @@ msgstr "Your template has been successfully deleted."
|
||||
msgid "Your template will be duplicated."
|
||||
msgstr "Your template will be duplicated."
|
||||
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:220
|
||||
#: apps/web/src/app/(dashboard)/templates/[id]/edit-template.tsx:199
|
||||
msgid "Your templates has been saved successfully."
|
||||
msgstr "Your templates has been saved successfully."
|
||||
|
||||
|
||||
@@ -1,792 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2024-07-24 13:01+1000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-09-19 09:18\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Crowdin-Project: documenso-app\n"
|
||||
"X-Crowdin-Project-ID: 694691\n"
|
||||
"X-Crowdin-Language: fr\n"
|
||||
"X-Crowdin-File: common.po\n"
|
||||
"X-Crowdin-File-ID: 4\n"
|
||||
|
||||
#: packages/ui/primitives/data-table-pagination.tsx:30
|
||||
msgid "{0} of {1} row(s) selected."
|
||||
msgstr "{0} sur {1} ligne(s) sélectionnée(s)."
|
||||
|
||||
#: packages/ui/primitives/data-table-pagination.tsx:41
|
||||
msgid "{visibleRows, plural, one {Showing # result.} other {Showing # results.}}"
|
||||
msgstr "{visibleRows, plural, one {Affichage de # résultat.} other {Affichage de # résultats.}}"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:53
|
||||
msgid "<0>Inherit authentication method</0> - Use the global action signing authentication method configured in the \"General Settings\" step"
|
||||
msgstr "<0>Hériter du méthode d'authentification</0> - Utiliser la méthode d'authentification de signature d'action globale configurée dans l'étape \"Paramètres Générales\""
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:95
|
||||
msgid "<0>No restrictions</0> - No authentication required"
|
||||
msgstr "<0>Aucune restriction</0> - Aucune authentification requise"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:77
|
||||
msgid "<0>No restrictions</0> - The document can be accessed directly by the URL sent to the recipient"
|
||||
msgstr "<0>Aucune restriction</0> - Le document peut être accédé directement par l'URL envoyée au destinataire"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:75
|
||||
msgid "<0>None</0> - No authentication required"
|
||||
msgstr "<0>Aucun</0> - Aucune authentification requise"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:89
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:69
|
||||
msgid "<0>Require 2FA</0> - The recipient must have an account and 2FA enabled via their settings"
|
||||
msgstr "<0>Exiger 2FA</0> - Le destinataire doit avoir un compte et 2FA activé via ses paramètres"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:72
|
||||
msgid "<0>Require account</0> - The recipient must be signed in to view the document"
|
||||
msgstr "<0>Exiger un compte</0> - Le destinataire doit être connecté pour voir le document"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:83
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:63
|
||||
msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings"
|
||||
msgstr "<0>Exiger une clé d'accès</0> - Le destinataire doit avoir un compte et une clé d'accès configurée via ses paramètres"
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:69
|
||||
msgid "Add a document"
|
||||
msgstr "Ajouter un document"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:336
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:339
|
||||
msgid "Add a URL to redirect the user to once the document is signed"
|
||||
msgstr "Ajouter une URL pour rediriger l'utilisateur une fois le document signé"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:248
|
||||
msgid "Add an external ID to the document. This can be used to identify the document in external systems."
|
||||
msgstr "Ajouter un ID externe au document. Cela peut être utilisé pour identifier le document dans des systèmes externes."
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:256
|
||||
msgid "Add an external ID to the template. This can be used to identify in external systems."
|
||||
msgstr "Ajouter un ID externe au modèle. Cela peut être utilisé pour identifier dans des systèmes externes."
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:177
|
||||
msgid "Add another option"
|
||||
msgstr "Ajouter une autre option"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:230
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx:167
|
||||
msgid "Add another value"
|
||||
msgstr "Ajouter une autre valeur"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:662
|
||||
msgid "Add myself"
|
||||
msgstr "Ajoutez-moi"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
|
||||
msgid "Add Myself"
|
||||
msgstr "Ajoutez-moi"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
|
||||
msgid "Add Placeholder Recipient"
|
||||
msgstr "Ajouter un destinataire de substitution"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:651
|
||||
msgid "Add Signer"
|
||||
msgstr "Ajouter un signataire"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:70
|
||||
msgid "Add text"
|
||||
msgstr "Ajouter du texte"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:75
|
||||
msgid "Add text to the field"
|
||||
msgstr "Ajouter du texte au champ"
|
||||
|
||||
#: packages/lib/constants/teams.ts:10
|
||||
msgid "Admin"
|
||||
msgstr "Administrateur"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:230
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:238
|
||||
msgid "Advanced Options"
|
||||
msgstr "Options avancées"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:565
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:402
|
||||
msgid "Advanced settings"
|
||||
msgstr "Paramètres avancés"
|
||||
|
||||
#: packages/lib/constants/template.ts:21
|
||||
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 email."
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:8
|
||||
msgid "Approve"
|
||||
msgstr "Approuver"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:9
|
||||
msgid "Approved"
|
||||
msgstr "Approuvé"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:11
|
||||
msgid "Approver"
|
||||
msgstr "Approuveur"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:10
|
||||
msgid "Approving"
|
||||
msgstr "En attente d'approbation"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:276
|
||||
msgid "Black"
|
||||
msgstr "Noir"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:290
|
||||
msgid "Blue"
|
||||
msgstr "Bleu"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:287
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:193
|
||||
msgid "Cannot remove signer"
|
||||
msgstr "Impossible de retirer le signataire"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:17
|
||||
msgid "Cc"
|
||||
msgstr "Cc"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:14
|
||||
#: packages/lib/constants/recipient-roles.ts:16
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:15
|
||||
msgid "CC'd"
|
||||
msgstr "CC'd"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:83
|
||||
msgid "Character Limit"
|
||||
msgstr "Limite de caractères"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:993
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:788
|
||||
msgid "Checkbox"
|
||||
msgstr "Case à cocher"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:195
|
||||
msgid "Checkbox values"
|
||||
msgstr "Valeurs de case à cocher"
|
||||
|
||||
#: packages/ui/primitives/data-table.tsx:156
|
||||
msgid "Clear filters"
|
||||
msgstr "Effacer les filtres"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:310
|
||||
msgid "Clear Signature"
|
||||
msgstr "Effacer la signature"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:394
|
||||
msgid "Click to insert field"
|
||||
msgstr "Cliquez pour insérer un champ"
|
||||
|
||||
#: packages/ui/primitives/document-flow/missing-signature-field-dialog.tsx:44
|
||||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: packages/lib/constants/template.ts:12
|
||||
msgid "Configure Direct Recipient"
|
||||
msgstr "Configurer le destinataire direct"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:566
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:403
|
||||
msgid "Configure the {0} field"
|
||||
msgstr "Configurer le champ {0}"
|
||||
|
||||
#: packages/ui/primitives/document-flow/document-flow-root.tsx:141
|
||||
msgid "Continue"
|
||||
msgstr "Continuer"
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx:46
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "Copié dans le presse-papiers"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:360
|
||||
msgid "Custom Text"
|
||||
msgstr "Texte personnalisé"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:889
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:684
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:271
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:279
|
||||
msgid "Date Format"
|
||||
msgstr "Format de date"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
|
||||
msgid "Direct link receiver"
|
||||
msgstr "Receveur de lien direct"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:62
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:174
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:151
|
||||
msgid "Document access"
|
||||
msgstr "Accès au document"
|
||||
|
||||
#: packages/lib/constants/template.ts:20
|
||||
msgid "Document Creation"
|
||||
msgstr "Création de document"
|
||||
|
||||
#: packages/ui/components/document/document-download-button.tsx:68
|
||||
msgid "Download"
|
||||
msgstr "Télécharger"
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:162
|
||||
msgid "Drag & drop your PDF here."
|
||||
msgstr "Faites glisser et déposez votre PDF ici."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1019
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:814
|
||||
msgid "Dropdown"
|
||||
msgstr "Liste déroulante"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:148
|
||||
msgid "Dropdown options"
|
||||
msgstr "Options de liste déroulante"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:837
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:272
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:500
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:632
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:184
|
||||
msgid "Email Options"
|
||||
msgstr "Options d'email"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1082
|
||||
msgid "Empty field"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/template.ts:8
|
||||
msgid "Enable Direct Link Signing"
|
||||
msgstr "Activer la signature de lien direct"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:401
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
|
||||
msgid "Enable signing order"
|
||||
msgstr "Activer l'ordre de signature"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:84
|
||||
msgid "Enter password"
|
||||
msgstr "Entrez le mot de passe"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:216
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:241
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:249
|
||||
msgid "External ID"
|
||||
msgstr "ID externe"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:217
|
||||
msgid "Failed to save settings."
|
||||
msgstr "Échec de l'enregistrement des paramètres."
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:90
|
||||
msgid "Field character limit"
|
||||
msgstr "Limite de caractères du champ"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:107
|
||||
msgid "Field format"
|
||||
msgstr "Format du champ"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:50
|
||||
msgid "Field label"
|
||||
msgstr "Étiquette du champ"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:62
|
||||
msgid "Field placeholder"
|
||||
msgstr "Espace réservé du champ"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:64
|
||||
msgid "Global recipient action authentication"
|
||||
msgstr "Authentification d'action de destinataire globale"
|
||||
|
||||
#: packages/ui/primitives/document-flow/document-flow-root.tsx:142
|
||||
msgid "Go Back"
|
||||
msgstr "Retourner"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:297
|
||||
msgid "Green"
|
||||
msgstr "Vert"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:72
|
||||
msgid "I am a signer of this document"
|
||||
msgstr "Je suis un signataire de ce document"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:75
|
||||
msgid "I am a viewer of this document"
|
||||
msgstr "Je suis un visualiseur de ce document"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:73
|
||||
msgid "I am an approver of this document"
|
||||
msgstr "Je suis un approuveur de ce document"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:74
|
||||
msgid "I am required to receive a copy of this document"
|
||||
msgstr "Je dois recevoir une copie de ce document"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:74
|
||||
#~ msgid "I am required to recieve a copy of this document"
|
||||
#~ msgstr "I am required to recieve a copy of this document"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:29
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:87
|
||||
msgid "Inherit authentication method"
|
||||
msgstr "Hériter de la méthode d'authentification"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:64
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:69
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:45
|
||||
msgid "Label"
|
||||
msgstr "Étiquette"
|
||||
|
||||
#: packages/lib/constants/teams.ts:11
|
||||
msgid "Manager"
|
||||
msgstr "Gestionnaire"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:168
|
||||
msgid "Max"
|
||||
msgstr "Max"
|
||||
|
||||
#: packages/lib/constants/teams.ts:12
|
||||
msgid "Member"
|
||||
msgstr "Membre"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-subject.tsx:95
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:215
|
||||
msgid "Message <0>(Optional)</0>"
|
||||
msgstr "Message <0>(Optionnel)</0>"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:156
|
||||
msgid "Min"
|
||||
msgstr "Min"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:863
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:298
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:535
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:541
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:658
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:52
|
||||
msgid "Needs to approve"
|
||||
msgstr "Nécessite une approbation"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:31
|
||||
msgid "Needs to sign"
|
||||
msgstr "Nécessite une signature"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:73
|
||||
msgid "Needs to view"
|
||||
msgstr "Nécessite une visualisation"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:674
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:497
|
||||
msgid "No recipient matching this description was found."
|
||||
msgstr "Aucun destinataire correspondant à cette description n'a été trouvé."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:690
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:513
|
||||
msgid "No recipients with this role"
|
||||
msgstr "Aucun destinataire avec ce rôle"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:30
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:43
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:31
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:46
|
||||
msgid "No restrictions"
|
||||
msgstr "Aucune restriction"
|
||||
|
||||
#: packages/ui/primitives/data-table.tsx:148
|
||||
msgid "No results found"
|
||||
msgstr "Aucun résultat trouvé"
|
||||
|
||||
#: packages/ui/primitives/document-flow/missing-signature-field-dialog.tsx:30
|
||||
msgid "No signature field found"
|
||||
msgstr "Aucun champ de signature trouvé"
|
||||
|
||||
#: packages/ui/primitives/combobox.tsx:60
|
||||
#: packages/ui/primitives/multi-select-combobox.tsx:153
|
||||
msgid "No value found."
|
||||
msgstr "Aucune valeur trouvée."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:941
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:736
|
||||
msgid "Number"
|
||||
msgstr "Numéro"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:100
|
||||
msgid "Number format"
|
||||
msgstr "Format de numéro"
|
||||
|
||||
#: packages/lib/constants/template.ts:9
|
||||
msgid "Once enabled, you can select any active recipient to be a direct link signing recipient, or create a new one. This recipient type cannot be edited or deleted."
|
||||
msgstr "Une fois activé, vous pouvez sélectionner n'importe quel destinataire actif pour être un destinataire de signature de lien direct ou en créer un nouveau. Ce type de destinataire ne peut pas être modifié ou supprimé."
|
||||
|
||||
#: packages/lib/constants/template.ts:17
|
||||
msgid "Once your template is set up, share the link anywhere you want. The person who opens the link will be able to enter their information in the direct link recipient field and complete any other fields assigned to them."
|
||||
msgstr "Une fois votre modèle configuré, partagez le lien où vous le souhaitez. La personne qui ouvre le lien pourra saisir ses informations dans le champ de destinataire de lien direct et remplir tout autre champ qui lui est attribué."
|
||||
|
||||
#: packages/ui/primitives/data-table-pagination.tsx:77
|
||||
msgid "Page {0} of {1}"
|
||||
msgstr "Page {0} sur {1}"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:62
|
||||
msgid "Password Required"
|
||||
msgstr "Mot de passe requis"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:154
|
||||
msgid "Pick a number"
|
||||
msgstr "Choisissez un numéro"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:76
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:81
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:57
|
||||
msgid "Placeholder"
|
||||
msgstr "Espace réservé"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:967
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:762
|
||||
msgid "Radio"
|
||||
msgstr "Radio"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx:133
|
||||
msgid "Radio values"
|
||||
msgstr "Valeurs radio"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:184
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:137
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:136
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx:122
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:114
|
||||
msgid "Read only"
|
||||
msgstr "Lecture seule"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:95
|
||||
msgid "Receives copy"
|
||||
msgstr "Recevoir une copie"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:215
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:169
|
||||
msgid "Recipient action authentication"
|
||||
msgstr "Authentification d'action de destinataire"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:283
|
||||
msgid "Red"
|
||||
msgstr "Rouge"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:329
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:332
|
||||
msgid "Redirect URL"
|
||||
msgstr "URL de redirection"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1069
|
||||
msgid "Remove"
|
||||
msgstr "Retirer"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:174
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:127
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:126
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/radio-field.tsx:112
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/text-field.tsx:104
|
||||
msgid "Required field"
|
||||
msgstr "Champ requis"
|
||||
|
||||
#: packages/ui/primitives/data-table-pagination.tsx:55
|
||||
msgid "Rows per page"
|
||||
msgstr "Lignes par page"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:286
|
||||
msgid "Save"
|
||||
msgstr "Sauvegarder"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:848
|
||||
msgid "Save Template"
|
||||
msgstr "Sauvegarder le modèle"
|
||||
|
||||
#: packages/ui/components/common/language-switcher-dialog.tsx:34
|
||||
msgid "Search languages..."
|
||||
msgstr "Rechercher des langues..."
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:105
|
||||
msgid "Select"
|
||||
msgstr "Sélectionner"
|
||||
|
||||
#: packages/ui/primitives/combobox.tsx:38
|
||||
msgid "Select an option"
|
||||
msgstr "Sélectionner une option"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:137
|
||||
msgid "Select at least"
|
||||
msgstr "Sélectionnez au moins"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:95
|
||||
msgid "Select default option"
|
||||
msgstr "Sélectionner l'option par défaut"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-subject.tsx:124
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:34
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:64
|
||||
msgid "Send"
|
||||
msgstr "Envoyer"
|
||||
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:41
|
||||
msgid "Send Document"
|
||||
msgstr "Envoyer le document"
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx:135
|
||||
msgid "Share Signature Card"
|
||||
msgstr "Partager la carte de signature"
|
||||
|
||||
#: packages/lib/constants/template.ts:16
|
||||
msgid "Share the Link"
|
||||
msgstr "Partager le lien"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:680
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
|
||||
msgid "Show advanced settings"
|
||||
msgstr "Afficher les paramètres avancés"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:20
|
||||
msgid "Sign"
|
||||
msgstr "Signer"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:785
|
||||
#: packages/ui/primitives/document-flow/add-signature.tsx:323
|
||||
#: packages/ui/primitives/document-flow/field-icon.tsx:52
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:580
|
||||
msgid "Signature"
|
||||
msgstr "Signature"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:21
|
||||
msgid "Signed"
|
||||
msgstr "Signé"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:23
|
||||
msgid "Signer"
|
||||
msgstr "Signataire"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:22
|
||||
msgid "Signing"
|
||||
msgstr "Signature en cours"
|
||||
|
||||
#: packages/ui/primitives/document-flow/missing-signature-field-dialog.tsx:34
|
||||
msgid "Some signers have not been assigned a signature field. Please assign at least 1 signature field to each signer before proceeding."
|
||||
msgstr "Certains signataires n'ont pas été assignés à un champ de signature. Veuillez assigner au moins 1 champ de signature à chaque signataire avant de continuer."
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx:51
|
||||
msgid "Something went wrong"
|
||||
msgstr "Quelque chose a mal tourné"
|
||||
|
||||
#: packages/ui/primitives/data-table.tsx:136
|
||||
msgid "Something went wrong."
|
||||
msgstr "Quelque chose a mal tourné."
|
||||
|
||||
#: packages/ui/primitives/document-flow/document-flow-root.tsx:107
|
||||
msgid "Step <0>{step} of {maxStep}</0>"
|
||||
msgstr "Étape <0>{step} sur {maxStep}</0>"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-subject.tsx:78
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:195
|
||||
msgid "Subject <0>(Optional)</0>"
|
||||
msgstr "Objet <0>(Optionnel)</0>"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:97
|
||||
msgid "Submit"
|
||||
msgstr "Soumettre"
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:134
|
||||
msgid "Template title"
|
||||
msgstr "Titre du modèle"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:915
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:710
|
||||
msgid "Text"
|
||||
msgstr "Texte"
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:44
|
||||
msgid "The authentication required for recipients to sign fields"
|
||||
msgstr "L'authentification requise pour que les destinataires signent des champs"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:68
|
||||
msgid "The authentication required for recipients to sign the signature field."
|
||||
msgstr "L'authentification requise pour que les destinataires signent le champ de signature."
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-access-select.tsx:67
|
||||
msgid "The authentication required for recipients to view the document."
|
||||
msgstr "L'authentification requise pour que les destinataires visualisent le document."
|
||||
|
||||
#: packages/ui/components/document/document-send-email-message-helper.tsx:31
|
||||
msgid "The document's name"
|
||||
msgstr "Le nom du document"
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:52
|
||||
msgid "The password you have entered is incorrect. Please try again."
|
||||
msgstr "Le mot de passe que vous avez entré est incorrect. Veuillez réessayer."
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:103
|
||||
msgid "The recipient is not required to take any action and receives a copy of the document after it is completed."
|
||||
msgstr "Le destinataire n'est pas tenu de prendre des mesures et reçoit une copie du document après son achèvement."
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:60
|
||||
msgid "The recipient is required to approve the document for it to be completed."
|
||||
msgstr "Le destinataire doit approuver le document pour qu'il soit complété."
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:39
|
||||
msgid "The recipient is required to sign the document for it to be completed."
|
||||
msgstr "Le destinataire doit signer le document pour qu'il soit complété."
|
||||
|
||||
#: packages/ui/components/recipient/recipient-role-select.tsx:81
|
||||
msgid "The recipient is required to view the document for it to be completed."
|
||||
msgstr "Le destinataire doit visualiser le document pour qu'il soit complété."
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx:52
|
||||
msgid "The sharing link could not be created at this time. Please try again."
|
||||
msgstr "Le lien de partage n'a pas pu être créé pour le moment. Veuillez réessayer."
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx:47
|
||||
msgid "The sharing link has been copied to your clipboard."
|
||||
msgstr "Le lien de partage a été copié dans votre presse-papiers."
|
||||
|
||||
#: packages/ui/components/document/document-send-email-message-helper.tsx:25
|
||||
msgid "The signer's email"
|
||||
msgstr "L'email du signataire"
|
||||
|
||||
#: packages/ui/components/document/document-send-email-message-helper.tsx:19
|
||||
msgid "The signer's name"
|
||||
msgstr "Le nom du signataire"
|
||||
|
||||
#: packages/ui/components/document/document-global-auth-action-select.tsx:72
|
||||
msgid "This can be overriden by setting the authentication requirements directly on each recipient in the next step."
|
||||
msgstr "Cela peut être remplacé par le paramétrage direct des exigences d'authentification pour chaque destinataire à l'étape suivante."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:746
|
||||
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
|
||||
msgstr "Ce document a déjà été envoyé à ce destinataire. Vous ne pouvez plus modifier ce destinataire."
|
||||
|
||||
#: packages/ui/primitives/document-password-dialog.tsx:66
|
||||
msgid "This document is password protected. Please enter the password to view the document."
|
||||
msgstr "Ce document est protégé par mot de passe. Veuillez entrer le mot de passe pour visualiser le document."
|
||||
|
||||
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
|
||||
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
|
||||
msgstr "Ce champ ne peut pas être modifié ou supprimé. Lorsque vous partagez le lien direct de ce modèle ou l'ajoutez à votre profil public, toute personne qui y accède peut saisir son nom et son email, et remplir les champs qui lui sont attribués."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1050
|
||||
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:195
|
||||
#~ msgid "This signer has already received the document."
|
||||
#~ msgstr "Ce signataire a déjà reçu le document."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx:194
|
||||
msgid "This signer has already signed the document."
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
|
||||
msgid "This will override any global settings."
|
||||
msgstr "Cela remplacera tous les paramètres globaux."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:305
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx:309
|
||||
msgid "Time Zone"
|
||||
msgstr "Fuseau horaire"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx:153
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx:1033
|
||||
#: packages/ui/primitives/template-flow/add-template-fields.tsx:828
|
||||
msgid "To proceed further, please set at least one value for the {0} field."
|
||||
msgstr "Pour continuer, veuillez définir au moins une valeur pour le champ {0}."
|
||||
|
||||
#: packages/ui/primitives/document-flow/add-subject.tsx:124
|
||||
msgid "Update"
|
||||
msgstr "Mettre à jour"
|
||||
|
||||
#: packages/lib/constants/template.ts:13
|
||||
msgid "Update the role and add fields as required for the direct recipient. The individual who uses the direct link will sign the document as the direct recipient."
|
||||
msgstr "Mettez à jour le rôle et ajoutez des champs selon les besoins pour le destinataire direct. L'individu qui utilise le lien direct signera le document en tant que destinataire direct."
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:168
|
||||
msgid "Upgrade"
|
||||
msgstr "Améliorer"
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:70
|
||||
msgid "Upload Template Document"
|
||||
msgstr "Télécharger le document modèle"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:130
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:147
|
||||
msgid "Validation"
|
||||
msgstr "Validation"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:88
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx:93
|
||||
msgid "Value"
|
||||
msgstr "Valeur"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:26
|
||||
msgid "View"
|
||||
msgstr "Vue"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:27
|
||||
msgid "Viewed"
|
||||
msgstr "Vu"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:29
|
||||
msgid "Viewer"
|
||||
msgstr "Visiteur"
|
||||
|
||||
#: packages/lib/constants/recipient-roles.ts:28
|
||||
msgid "Viewing"
|
||||
msgstr "Visionnage"
|
||||
|
||||
#: packages/ui/primitives/signature-pad/signature-pad.tsx:280
|
||||
#~ msgid "White"
|
||||
#~ msgstr "White"
|
||||
|
||||
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:44
|
||||
msgid "You are about to send this document to the recipients. Are you sure you want to continue?"
|
||||
msgstr "Vous êtes sur le point d'envoyer ce document aux destinataires. Êtes-vous sûr de vouloir continuer ?"
|
||||
|
||||
#: packages/ui/components/document/document-send-email-message-helper.tsx:11
|
||||
msgid "You can use the following variables in your message:"
|
||||
msgstr "Vous pouvez utiliser les variables suivantes dans votre message :"
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:43
|
||||
msgid "You cannot upload documents at this time."
|
||||
msgstr "Vous ne pouvez pas télécharger de documents pour le moment."
|
||||
|
||||
#: packages/ui/primitives/document-dropzone.tsx:69
|
||||
msgid "You have reached your document limit."
|
||||
msgstr "Vous avez atteint votre limite de documents."
|
||||
File diff suppressed because one or more lines are too long
@@ -1,620 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2024-07-24 13:01+1000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-09-19 09:18\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Crowdin-Project: documenso-app\n"
|
||||
"X-Crowdin-Project-ID: 694691\n"
|
||||
"X-Crowdin-Language: fr\n"
|
||||
"X-Crowdin-File: marketing.po\n"
|
||||
"X-Crowdin-File-ID: 6\n"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:45
|
||||
msgid "{0}"
|
||||
msgstr "{0}"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:100
|
||||
msgid "5 standard documents per month"
|
||||
msgstr "5 documents standard par mois"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:198
|
||||
msgid "5 Users Included"
|
||||
msgstr "5 utilisateurs inclus"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:34
|
||||
msgid "A 10x better signing experience."
|
||||
msgstr "Une expérience de signature 10 fois meilleure."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:51
|
||||
msgid "Add document"
|
||||
msgstr "Ajouter un document"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:201
|
||||
msgid "Add More Users for {0}"
|
||||
msgstr "Ajouter plus d'utilisateurs pour {0}"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:165
|
||||
msgid "All our metrics, finances, and learnings are public. We believe in transparency and want to share our journey with you. You can read more about why here: <0>Announcing Open Metrics</0>"
|
||||
msgstr "Tous nos indicateurs, finances et apprentissages sont publics. Nous croyons en la transparence et souhaitons partager notre parcours avec vous. Vous pouvez en lire plus sur pourquoi ici : <0>Annonce de Open Metrics</0>"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:58
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:65
|
||||
msgid "Amount Raised"
|
||||
msgstr "Montant levé"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:145
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:189
|
||||
msgid "API Access"
|
||||
msgstr "Accès API"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:67
|
||||
msgid "Beautiful."
|
||||
msgstr "Beau."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:69
|
||||
msgid "Because signing should be celebrated. That’s why we care about the smallest detail in our product."
|
||||
msgstr "Parce que la signature doit être célébrée. C'est pourquoi nous nous soucions du moindre détail dans notre produit."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:35
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:57
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:36
|
||||
msgid "Blog"
|
||||
msgstr "Blog"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:64
|
||||
msgid "Build on top."
|
||||
msgstr "Construire dessus."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:163
|
||||
msgid "Can I use Documenso commercially?"
|
||||
msgstr "Puis-je utiliser Documenso commercialement ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:42
|
||||
msgid "Careers"
|
||||
msgstr "Carrières"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:36
|
||||
msgid "Changelog"
|
||||
msgstr "Changelog"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:85
|
||||
msgid "Choose a template from the community app store. Or submit your own template for others to use."
|
||||
msgstr "Choisissez un modèle dans la boutique d'applications communautaires. Ou soumettez votre propre modèle pour que d'autres puissent l'utiliser."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:219
|
||||
msgid "Community"
|
||||
msgstr "Communauté"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-completed-documents-chart.tsx:55
|
||||
msgid "Completed Documents"
|
||||
msgstr "Documents complets"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-completed-documents-chart.tsx:33
|
||||
msgid "Completed Documents per Month"
|
||||
msgstr "Documents complets par mois"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:65
|
||||
msgid "Connections"
|
||||
msgstr "Connexions"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:35
|
||||
msgid "Contact Us"
|
||||
msgstr "Contactez-nous"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:67
|
||||
msgid "Create connections and automations with Zapier and more to integrate with your favorite tools."
|
||||
msgstr "Créez des connexions et des automatisations avec Zapier et plus encore pour intégrer vos outils préférés."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:23
|
||||
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
|
||||
msgstr "Créez votre compte et commencez à utiliser la signature de documents à la pointe de la technologie. Une signature ouverte et belle est à votre portée."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/tooltip.tsx:35
|
||||
msgid "Customers with an Active Subscriptions."
|
||||
msgstr "Clients avec un abonnement actif."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:33
|
||||
msgid "Customise and expand."
|
||||
msgstr "Personnaliser et étendre."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:38
|
||||
msgid "Design"
|
||||
msgstr "Conception"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:44
|
||||
msgid "Designed for every stage of your journey."
|
||||
msgstr "Conçu pour chaque étape de votre parcours."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:40
|
||||
msgid "Direct Link"
|
||||
msgstr "Lien Direct"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:181
|
||||
msgid "Documenso is a community effort to create an open and vibrant ecosystem around a tool, everybody is free to use and adapt. By being truly open we want to create trusted infrastructure for the future of the internet."
|
||||
msgstr "Documenso est un effort collectif pour créer un écosystème ouvert et dynamique autour d'un outil, tout le monde est libre de l'utiliser et de l'adapter. En étant vraiment ouvert, nous voulons créer une infrastructure de confiance pour l'avenir d'Internet."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:28
|
||||
msgid "Documenso on X"
|
||||
msgstr "Documenso sur X"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:104
|
||||
msgid "Document signing,<0/>finally open source."
|
||||
msgstr "Signature de documents,<0/> enfin open source."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:33
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:50
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:28
|
||||
msgid "Documentation"
|
||||
msgstr "Documentation"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:110
|
||||
msgid "Easily embed Documenso into your product. Simply copy and paste our react widget into your application."
|
||||
msgstr "Intégrez facilement Documenso dans votre produit. Il vous suffit de copier et coller notre widget React dans votre application."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:42
|
||||
#~ msgid "Easy Sharing (Soon)."
|
||||
#~ msgstr "Easy Sharing (Soon)."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:46
|
||||
msgid "Easy Sharing."
|
||||
msgstr "Partage facile."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:148
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:192
|
||||
msgid "Email and Discord Support"
|
||||
msgstr "Support par e-mail et Discord"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:43
|
||||
msgid "Engagement"
|
||||
msgstr "Engagement"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:64
|
||||
msgid "Enter your details."
|
||||
msgstr "Entrez vos détails."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:16
|
||||
msgid "Enterprise Compliance, License or Technical Needs?"
|
||||
msgstr "Conformité des entreprises, besoins en licence ou techniques ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:128
|
||||
msgid "Everything you need for a great signing experience."
|
||||
msgstr "Tout ce dont vous avez besoin pour une excellente expérience de signature."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:45
|
||||
msgid "Fast."
|
||||
msgstr "Rapide."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:36
|
||||
msgid "Faster, smarter and more beautiful."
|
||||
msgstr "Plus rapide, plus intelligent et plus beau."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:210
|
||||
msgid "Finances"
|
||||
msgstr "Finances"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:38
|
||||
msgid "Follow us on X"
|
||||
msgstr "Suivez-nous sur X"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:172
|
||||
msgid "For companies looking to scale across multiple teams."
|
||||
msgstr "Pour les entreprises cherchant à se développer au sein de plusieurs équipes."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:85
|
||||
msgid "For small teams and individuals with basic needs."
|
||||
msgstr "Pour les petites équipes et les individus ayant des besoins de base."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:80
|
||||
msgid "Free"
|
||||
msgstr "Gratuit"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:26
|
||||
msgid "From the blog"
|
||||
msgstr "Du blog"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:9
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:17
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:33
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:41
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:49
|
||||
msgid "Full-Time"
|
||||
msgstr "Temps plein"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:87
|
||||
msgid "Get paid (Soon)."
|
||||
msgstr "Recevez une rémunération (Bientôt)."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:31
|
||||
msgid "Get started"
|
||||
msgstr "Commencez"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:75
|
||||
msgid "Get Started"
|
||||
msgstr "Commencez"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:47
|
||||
msgid "Get started today."
|
||||
msgstr "Commencez aujourd'hui."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/blog/page.tsx:30
|
||||
msgid "Get the latest news from Documenso, including product updates, team announcements and more!"
|
||||
msgstr "Obtenez les dernières nouvelles de Documenso, y compris les mises à jour de produits, les annonces d'équipe et plus encore !"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:233
|
||||
msgid "GitHub: Total Merged PRs"
|
||||
msgstr "GitHub : Total des PRs fusionnées"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:251
|
||||
msgid "GitHub: Total Open Issues"
|
||||
msgstr "GitHub : Total des problèmes ouverts"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:225
|
||||
msgid "GitHub: Total Stars"
|
||||
msgstr "GitHub : Nombre total d'étoiles"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:23
|
||||
msgid "Global Salary Bands"
|
||||
msgstr "Bandes de salaire globales"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:261
|
||||
msgid "Growth"
|
||||
msgstr "Croissance"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:134
|
||||
msgid "How can I contribute?"
|
||||
msgstr "Comment puis-je contribuer ?"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:105
|
||||
msgid "How do you handle my data?"
|
||||
msgstr "Comment gérez-vous mes données ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:118
|
||||
msgid "Individual"
|
||||
msgstr "Individuel"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:89
|
||||
msgid "Integrated payments with Stripe so you don’t have to worry about getting paid."
|
||||
msgstr "Paiements intégrés avec Stripe afin que vous n'ayez pas à vous soucier d'être payé."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:35
|
||||
msgid "Integrates with all your favourite tools."
|
||||
msgstr "S'intègre à tous vos outils préférés."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:289
|
||||
msgid "Is there more?"
|
||||
msgstr "Y a-t-il plus ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:44
|
||||
msgid "It’s up to you. Either clone our repository or rely on our easy to use hosting solution."
|
||||
msgstr "C'est à vous de décider. Soit vous clonez notre dépôt, soit vous vous fiez à notre solution d'hébergement simple à utiliser."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:49
|
||||
msgid "Join Date"
|
||||
msgstr "Date d'adhésion"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/call-to-action.tsx:19
|
||||
msgid "Join the Open Signing Movement"
|
||||
msgstr "Rejoignez le mouvement de signature ouverte"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:46
|
||||
msgid "Location"
|
||||
msgstr "Emplacement"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:66
|
||||
msgid "Make it your own through advanced customization and adjustability."
|
||||
msgstr "Faites-en votre propre grâce à une personnalisation avancée et un ajustement."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:199
|
||||
msgid "Merged PR's"
|
||||
msgstr "PRs fusionnées"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:234
|
||||
msgid "Merged PRs"
|
||||
msgstr "PRs fusionnées"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:40
|
||||
msgid "Monthly"
|
||||
msgstr "Mensuel"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:34
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:43
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-new-users-chart.tsx:52
|
||||
msgid "New Users"
|
||||
msgstr "Nouveaux utilisateurs"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:106
|
||||
msgid "No credit card required"
|
||||
msgstr "Aucune carte de crédit requise"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/callout.tsx:29
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:125
|
||||
msgid "No Credit Card required"
|
||||
msgstr "Aucune carte de crédit requise"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:61
|
||||
msgid "None of these work for you? Try self-hosting!"
|
||||
msgstr "Aucune de ces options ne fonctionne pour vous ? Essayez l'hébergement autonome !"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:194
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:252
|
||||
msgid "Open Issues"
|
||||
msgstr "Problèmes ouverts"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:42
|
||||
msgid "Open Source or Hosted."
|
||||
msgstr "Open Source ou hébergé."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:161
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:37
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:64
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:40
|
||||
msgid "Open Startup"
|
||||
msgstr "Startup ouverte"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:41
|
||||
msgid "OSS Friends"
|
||||
msgstr "Amis OSS"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:91
|
||||
msgid "Our custom templates come with smart rules that can help you save time and energy."
|
||||
msgstr "Nos modèles personnalisés sont dotés de règles intelligentes qui peuvent vous aider à gagner du temps et de l'énergie."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:20
|
||||
msgid "Our Enterprise License is great for large organizations looking to switch to Documenso for all their signing needs. It's available for our cloud offering as well as self-hosted setups and offers a wide range of compliance and Adminstration Features."
|
||||
msgstr "Notre licence entreprise est idéale pour les grandes organisations cherchant à passer à Documenso pour tous leurs besoins de signature. Elle est disponible pour notre offre cloud ainsi que pour des configurations auto-hébergées et propose un large éventail de fonctionnalités de conformité et d'administration."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/enterprise.tsx:20
|
||||
#~ msgid "Our Enterprise License is great large organizations looking to switch to Documenso for all their signing needs. It's availible for our cloud offering as well as self-hosted setups and offer a wide range of compliance and Adminstration Features."
|
||||
#~ msgstr "Our Enterprise License is great large organizations looking to switch to Documenso for all their signing needs. It's availible for our cloud offering as well as self-hosted setups and offer a wide range of compliance and Adminstration Features."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:65
|
||||
msgid "Our self-hosted option is great for small teams and individuals who need a simple solution. You can use our docker based setup to get started in minutes. Take control with full customizability and data ownership."
|
||||
msgstr "Notre option auto-hébergée est idéale pour les petites équipes et les individus qui ont besoin d'une solution simple. Vous pouvez utiliser notre configuration basée sur Docker pour commencer en quelques minutes. Prenez le contrôle avec une personnalisation complète et une propriété des données."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/data.ts:25
|
||||
#~ msgid "Part-Time"
|
||||
#~ msgstr "Temps partiel"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:151
|
||||
msgid "Premium Profile Name"
|
||||
msgstr "Nom de profil premium"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:40
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:31
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:42
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:24
|
||||
msgid "Pricing"
|
||||
msgstr "Prix"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:43
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:53
|
||||
msgid "Privacy"
|
||||
msgstr "Confidentialité"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:58
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:108
|
||||
msgid "React Widget (Soon)."
|
||||
msgstr "Widget React (Bientôt)."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:48
|
||||
msgid "Receive your personal link to share with everyone you care about."
|
||||
msgstr "Recevez votre lien personnel à partager avec tous ceux qui vous tiennent à cœur."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:37
|
||||
msgid "Role"
|
||||
msgstr "Rôle"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:37
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:40
|
||||
msgid "Salary"
|
||||
msgstr "Salaire"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:62
|
||||
msgid "Save $60 or $120"
|
||||
msgstr "Économisez 60 $ ou 120 $"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/i18n-switcher.tsx:47
|
||||
#~ msgid "Search languages..."
|
||||
#~ msgstr "Search languages..."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:109
|
||||
msgid "Securely. Our data centers are located in Frankfurt (Germany), giving us the best local privacy laws. We are very aware of the sensitive nature of our data and follow best practices to ensure the security and integrity of the data entrusted to us."
|
||||
msgstr "De manière sécurisée. Nos centres de données sont situés à Francfort (Allemagne), ce qui nous permet de bénéficier des meilleures lois locales sur la confidentialité. Nous sommes très conscients de la nature sensible de nos données et suivons les meilleures pratiques pour garantir la sécurité et l'intégrité des données qui nous sont confiées."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/share-connect-paid-widget-bento.tsx:37
|
||||
msgid "Send, connect, receive and embed everywhere."
|
||||
msgstr "Envoyer, connecter, recevoir et intégrer partout."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:34
|
||||
msgid "Seniority"
|
||||
msgstr "Ancienneté"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:39
|
||||
msgid "Shop"
|
||||
msgstr "Boutique"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:63
|
||||
msgid "Sign"
|
||||
msgstr "Signer"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:72
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:61
|
||||
msgid "Sign in"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/header.tsx:77
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:57
|
||||
msgid "Sign up"
|
||||
msgstr "S'inscrire"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:22
|
||||
msgid "Signing Process"
|
||||
msgstr "Processus de signature"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:94
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:136
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:180
|
||||
msgid "Signup Now"
|
||||
msgstr "Inscrivez-vous maintenant"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:89
|
||||
msgid "Smart."
|
||||
msgstr "Intelligent."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:132
|
||||
msgid "Star on GitHub"
|
||||
msgstr "Étoile sur GitHub"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:226
|
||||
msgid "Stars"
|
||||
msgstr "Étoiles"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:40
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:44
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/footer.tsx:34
|
||||
#: apps/marketing/src/components/(marketing)/mobile-navigation.tsx:48
|
||||
msgid "Support"
|
||||
msgstr "Soutien"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/team-members.tsx:26
|
||||
msgid "Team"
|
||||
msgstr "Équipe"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:195
|
||||
msgid "Team Inbox"
|
||||
msgstr "Boîte de réception de l'équipe"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:28
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:162
|
||||
msgid "Teams"
|
||||
msgstr "Équipes"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:83
|
||||
msgid "Template Store (Soon)."
|
||||
msgstr "Boutique de modèles (Bientôt)."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:138
|
||||
msgid "That's awesome. You can take a look at the current <0>Issues</0> and join our <1>Discord Community</1> to keep up to date, on what the current priorities are. In any case, we are an open community and welcome all input, technical and non-technical ❤️"
|
||||
msgstr "C'est génial. Vous pouvez consulter les <0>Problèmes</0> actuels et rejoindre notre <1>Communauté Discord</1> pour rester à jour sur ce qui est actuellement prioritaire. Dans tous les cas, nous sommes une communauté ouverte et accueillons toutes les contributions, techniques et non techniques ❤️"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:293
|
||||
msgid "This page is evolving as we learn what makes a great signing company. We'll update it when we have more to share."
|
||||
msgstr "Cette page évolue à mesure que nous apprenons ce qui fait une grande entreprise de signature. Nous la mettrons à jour lorsque nous aurons plus à partager."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/salary-bands.tsx:31
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/total-signed-documents-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/total-signed-documents-chart.tsx:55
|
||||
msgid "Total Completed Documents"
|
||||
msgstr "Documents totalisés complétés"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:267
|
||||
#: apps/marketing/src/app/(marketing)/open/page.tsx:268
|
||||
msgid "Total Customers"
|
||||
msgstr "Total des clients"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/funding-raised.tsx:29
|
||||
msgid "Total Funding Raised"
|
||||
msgstr "Total des fonds levés"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:30
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:43
|
||||
#: apps/marketing/src/app/(marketing)/open/monthly-total-users-chart.tsx:52
|
||||
msgid "Total Users"
|
||||
msgstr "Total des utilisateurs"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/open-build-template-bento.tsx:31
|
||||
msgid "Truly your own."
|
||||
msgstr "Vraiment le vôtre."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/callout.tsx:27
|
||||
#: apps/marketing/src/components/(marketing)/hero.tsx:123
|
||||
msgid "Try our Free Plan"
|
||||
msgstr "Essayez notre plan gratuit"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:20
|
||||
msgid "Twitter Stats"
|
||||
msgstr "Statistiques Twitter"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:142
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:186
|
||||
msgid "Unlimited Documents per Month"
|
||||
msgstr "Documents illimités par mois"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:103
|
||||
msgid "Up to 10 recipients per document"
|
||||
msgstr "Jusqu'à 10 destinataires par document"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/singleplayer/client.tsx:52
|
||||
msgid "Upload a document and add fields."
|
||||
msgstr "Téléchargez un document et ajoutez des champs."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:123
|
||||
msgid "Using our hosted version is the easiest way to get started, you can simply subscribe and start signing your documents. We take care of the infrastructure, so you can focus on your business. Additionally, when using our hosted version you benefit from our trusted signing certificates which helps you to build trust with your customers."
|
||||
msgstr "Utiliser notre version hébergée est le moyen le plus simple de commencer, vous pouvez simplement vous abonner et commencer à signer vos documents. Nous nous occupons de l'infrastructure, vous pouvez vous concentrer sur votre entreprise. De plus, en utilisant notre version hébergée, vous bénéficiez de nos certificats de signature de confiance, ce qui vous aide à instaurer une relation de confiance avec vos clients."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/open/typefully.tsx:33
|
||||
msgid "View all stats"
|
||||
msgstr "Voir toutes les statistiques"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:195
|
||||
msgid "We are happy to assist you at <0>support@documenso.com</0> or <1>in our Discord-Support-Channel</1> please message either Lucas or Timur to get added to the channel if you are not already a member."
|
||||
msgstr "Nous sommes heureux de vous aider à <0>support@documenso.com</0> ou <1>dans notre canal de support Discord</1>, veuillez envoyer un message à Lucas ou Timur pour être ajouté au canal si vous n'êtes pas déjà membre."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:89
|
||||
msgid "What is the difference between the plans?"
|
||||
msgstr "Quelle est la différence entre les plans ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/faster-smarter-beautiful-bento.tsx:47
|
||||
msgid "When it comes to sending or receiving a contract, you can count on lightning-fast speeds."
|
||||
msgstr "En ce qui concerne l'envoi ou la réception d'un contrat, vous pouvez compter sur des vitesses ultrarapides."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:191
|
||||
msgid "Where can I get support?"
|
||||
msgstr "Où puis-je obtenir du support ?"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:177
|
||||
msgid "Why should I prefer Documenso over DocuSign or some other signing tool?"
|
||||
msgstr "Pourquoi devrais-je préférer Documenso à DocuSign ou à un autre outil de signature ?"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:119
|
||||
msgid "Why should I use your hosting service?"
|
||||
msgstr "Pourquoi devrais-je utiliser votre service d'hébergement ?"
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/pricing-table.tsx:60
|
||||
msgid "Yearly"
|
||||
msgstr "Annuel"
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:167
|
||||
msgid "Yes! Documenso is offered under the GNU AGPL V3 open source license. This means you can use it for free and even modify it to fit your needs, as long as you publish your changes under the same license."
|
||||
msgstr "Oui ! Documenso est proposé sous la licence open source GNU AGPL V3. Cela signifie que vous pouvez l'utiliser gratuitement et même le modifier pour répondre à vos besoins, tant que vous publiez vos modifications sous la même licence."
|
||||
|
||||
#: apps/marketing/src/app/(marketing)/pricing/page.tsx:93
|
||||
msgid "You can self-host Documenso for free or use our ready-to-use hosted version. The hosted version comes with additional support, painless scalability and more. Early adopters will get access to all features we build this year, for no additional cost! Forever! Yes, that includes multiple users per account later. If you want Documenso for your enterprise, we are happy to talk about your needs."
|
||||
msgstr "Vous pouvez auto-héberger Documenso gratuitement ou utiliser notre version hébergée prête à l'emploi. La version hébergée est accompagnée d'une assistance supplémentaire, d'une montée en charge sans effort et d'autres avantages. Les premiers adoptants auront accès à toutes les fonctionnalités que nous construirons cette année, sans coût supplémentaire ! Pour toujours ! Oui, cela inclut plusieurs utilisateurs par compte à l'avenir. Si vous souhaitez Documenso pour votre entreprise, nous serons heureux de discuter de vos besoins."
|
||||
|
||||
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
|
||||
msgid "Your browser does not support the video tag."
|
||||
msgstr "Votre navigateur ne prend pas en charge la balise vidéo."
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user