Compare commits

...
80 Commits
Author SHA1 Message Date
Alex van Andel 1566a80e40 v3.1.4
release.yml / release (push) Canceled after 0s
2023-07-21 10:02:01 +01:00
Nafees NazikandCarina Wollendorfer 797d3a7f98 fix: set up organization field validation (#10154)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-07-21 08:48:43 +00:00
c7a276eb1d fix: remove app dialog while removing installed calendar (#10234)
* Fix remove app dialog while removing installed calendar

* fix: dialog in webhook, otp

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

* fix: more dialogs

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

* fix: margin

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-07-21 08:46:16 +00:00
Crowdin Bot 1709e23135 New Crowdin translations by Github Action 2023-07-21 08:35:03 +00:00
Leo Giovanetti d1778fdce8 fix: 2FA from CAL to GOOGLE (#10288)
* Fixing 2FA from CAL to GOOGLE

* Missing change

* Missing logic for converted providers

* Fixing edge case and applying feedback

* Leftovers
2023-07-21 09:32:03 +01:00
Joe Au-Yeung b49952b8d8 Fix prettier error on App component (#10287) 2023-07-21 09:31:02 +01:00
Alex van Andel 5b280b2188 fix: team event emails; sending & email subject (#10289) 2023-07-20 19:29:08 -04:00
Alex van Andel 3818093652 fix: Add attendees to getLuckyUser algorithm (#10285)
* Add attendees to getLuckyUser algorithm

* Fix unit test for getLuckyUser
2023-07-20 22:51:15 +01:00
Crowdin Bot 56f4310c24 New Crowdin translations by Github Action 2023-07-20 20:31:50 +00:00
Peer Richelsen 7ec7195ae9 fixed empty screen width (#10278) 2023-07-20 20:29:05 +00:00
Joe Au-Yeung 514db3466f fix: Flaky 2FA tests (#10283) 2023-07-20 19:40:35 +00:00
alannncandPeer Richelsen cd88b688f4 fix: including parentId when filter by eventTypeId happens (#10262)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-07-20 12:19:13 -07:00
Omar López 939a32813f Revert "chore: Make embed and app-store tests required" (#10282) 2023-07-20 11:58:07 -07:00
Joe Au-Yeung 66c1e29d91 fix: Default to Daily if Viable (#10279)
* Default to daily if viable

* Add Zod schema parsing
2023-07-20 12:57:10 -04:00
Crowdin Bot 3c57082fa6 New Crowdin translations by Github Action 2023-07-20 12:10:47 +00:00
Hariom Balhara fc4a2bd186 make embed and app-store tests required (#10271) 2023-07-20 14:08:09 +02:00
Hariom Balhara 3f900966b0 Fix flash of non-transparent background (#10265) 2023-07-20 09:17:46 +02:00
Leo GiovanettiandOmar López 8ba4b4d50e feat: Pending members selection (#10168)
* Pending members selection

* Discard changes to .vscode/launch.json

* revert yarn.lock

---------

Co-authored-by: Omar López <zomars@me.com>
2023-07-20 11:23:15 +05:30
GitStart-Cal.comandgitstart-calcom d2104dac5a test: Create unit tests for react components in packages/ui/components/breadcrumb (CALCOM-614) (#10256)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-07-20 07:13:23 +02:00
GitStart-Cal.comandgitstart-calcom 9ad2731358 test: add unit tests for packages/ui/components/badge (CALCOM-613) (#10255)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-07-20 07:11:53 +02:00
GitStart-Cal.comandgitstart-calcom c34fdab5af test: Create unit tests for react components in packages/ui/components/card (CALCOM-617) (#10257)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-07-20 07:06:15 +02:00
Hariom BalharaandCarina Wollendorfer f1c981fdcf feat: firstAndLastName variant for name field (#8671)
* Add split full name variant

* Share propsType across fieldTypes and components

* Simplify Components

* Add assertions for required field indicator

* Fix test as name cant be used as a custom field right now

* Make it disabled during reschedule

* Fix UI issues in dark mode

* Support adding links in boolean checkbox

* Revert "Support adding links in boolean checkbox"

This reverts commit 31252f8a5f445f8289a09445124109a4a9c3d33b.

* Make sure getBookingFields isnt import client side

* PR feedback addressed from Carina

* DRY Code

* Fix Dialog

---------

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-07-20 07:03:50 +02:00
Anik Dhabal Babu 47f65bb19f fix: More Brand color for calendar view (#10252) 2023-07-20 00:32:25 +02:00
GitStart-Cal.comandgitstart-calcom 587d3c1088 fix: duplicate event-type dialog not using the new dialog footer (CALCOM-10258) (#10260)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-07-20 00:15:03 +02:00
sean-brydon 610c86837a feat: orgs - user management v2
figma: https://www.figma.com/file/ZJNAFHCAq6rnuGRgUFxjzQ/Organizations----New-features?type=design&node-id=4304-330348&mode=design&t=nKonHZpucwxnqwQI-4 (Not all features are in this PR)
loom: https://www.loom.com/share/30e8ef20a5b34a708dca160d8c04ae6f

shoutout @shadcn for the base of this table <3 

Member View: 
![CleanShot 2023-07-14 at 14 09 02](https://github.com/calcom/cal.com/assets/55134778/5db6eedb-bece-4955-91f0-9f2b3b042300)

Admin view:
![CleanShot 2023-07-14 at 14 09 07](https://github.com/calcom/cal.com/assets/55134778/708c624d-1990-4075-8b32-d4587d09deff)

How to test 
- Create ORG
- add members
- view settings -> orgs -> members
2023-07-19 12:45:13 -07:00
Crowdin Bot 676452b4f4 New Crowdin translations by Github Action 2023-07-19 18:47:31 +00:00
Carina WollendorferandCarinaWolli 8a432b45a4 fix: issue with date overrides in some timezones (#10254)
* fix date overrides

* add test

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-07-19 19:44:41 +01:00
Crowdin Bot 92ad652666 New Crowdin translations by Github Action 2023-07-19 16:15:23 +00:00
Mingjie Jiang 617ddcaa3b chore: Improve and standardize simplified and traditional Chinese localizations (#9902) 2023-07-19 16:12:09 +00:00
Crowdin Bot ef7f3e7900 New Crowdin translations by Github Action 2023-07-19 16:10:58 +00:00
4e0a549a50 fix: Fix bookingPage UI issues in dark mode (#10203)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-07-19 16:07:07 +00:00
Crowdin Bot 8f95d27469 New Crowdin translations by Github Action 2023-07-19 15:44:41 +00:00
8902f7efa1 fix: /event-type /apps - doesn't match designs (CALCOM-9180) (#9549)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-07-19 17:41:37 +02:00
GitStart-Cal.comandgitstart-calcom bd7eadd721 test: Create unit tests for react components in packages/ui/components/alert (tests-alert-component) (#9897)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-07-19 17:22:41 +02:00
Crowdin Bot 02e34a7bde New Crowdin translations by Github Action 2023-07-19 15:21:40 +00:00
sean-brydonandShivam Kalra d51e1ab47d fix: Fixes error for unknown JSON when creating an account (#10248)
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
2023-07-19 15:18:31 +00:00
Crowdin Bot ebe60c36bd New Crowdin translations by Github Action
release.yml / release (push) Canceled after 0s
2023-07-19 14:33:31 +00:00
Monto 26e458be6d feat: dynamic time format rendering in workflows based on user settings (#10229) 2023-07-19 10:30:37 -04:00
Crowdin Bot 1ad4f7247e New Crowdin translations by Github Action 2023-07-19 12:37:55 +00:00
Crowdin Bot e0237acac9 New Crowdin translations by Github Action 2023-07-19 12:35:34 +00:00
Crowdin Bot 2dc0bb4888 New Crowdin translations by Github Action 2023-07-19 12:33:09 +00:00
sean-brydon dfffd8b577 fix: revert i18n hook changes (#10249) 2023-07-19 12:30:25 +00:00
Crowdin Bot e6f2ba2c25 New Crowdin translations by Github Action 2023-07-19 09:22:27 +00:00
sean-brydonandKeith Williams 628a29e89c chore: fixing some initial re-renders (#10185)
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-07-19 09:19:53 +00:00
Crowdin Bot 2fd9ef2733 New Crowdin translations by Github Action 2023-07-19 09:05:08 +00:00
Crowdin Bot c9f2d6bc93 New Crowdin translations by Github Action 2023-07-19 09:01:24 +00:00
Peer Richelsen a83aea30da Update package.json 2023-07-19 10:58:27 +02:00
Hariom BalharaandShivam Kalra b516a2af44 Get OAuth working for local (#10054)
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
2023-07-19 09:15:05 +02:00
Crowdin Bot d0e831975d New Crowdin translations by Github Action 2023-07-19 06:40:31 +00:00
Crowdin Bot b906c7caf7 New Crowdin translations by Github Action 2023-07-19 06:37:40 +00:00
Crowdin Bot 152dbe58c9 New Crowdin translations by Github Action 2023-07-19 06:34:49 +00:00
Crowdin Bot b4c154a6af New Crowdin translations by Github Action 2023-07-19 06:32:11 +00:00
Crowdin Bot 99cea7a326 New Crowdin translations by Github Action 2023-07-19 06:29:40 +00:00
Crowdin Bot d0ae519851 New Crowdin translations by Github Action 2023-07-19 06:27:16 +00:00
Crowdin Bot d185c665b8 New Crowdin translations by Github Action 2023-07-19 06:24:21 +00:00
Crowdin Bot baa9ddf46a New Crowdin translations by Github Action 2023-07-19 06:21:52 +00:00
Alex van Andel e8f5090acc Fix: Flaky 2FA test due to waiting redundant Enter (#10236) 2023-07-19 08:19:16 +02:00
Crowdin Bot 0661b96cd2 New Crowdin translations by Github Action 2023-07-19 05:10:16 +00:00
Crowdin Bot 3a64506c9e New Crowdin translations by Github Action 2023-07-19 05:07:31 +00:00
Crowdin Bot f1b705e022 New Crowdin translations by Github Action 2023-07-19 05:05:00 +00:00
Crowdin Bot c768d52539 New Crowdin translations by Github Action 2023-07-19 05:02:24 +00:00
Crowdin Bot 7d3ba5c55c New Crowdin translations by Github Action 2023-07-19 04:59:34 +00:00
Crowdin Bot e643afaa80 New Crowdin translations by Github Action 2023-07-19 04:57:05 +00:00
Crowdin Bot 4cd3479cfd New Crowdin translations by Github Action 2023-07-19 04:54:39 +00:00
Crowdin Bot 7efddfd213 New Crowdin translations by Github Action 2023-07-19 04:51:59 +00:00
Crowdin Bot a8c362dbf3 New Crowdin translations by Github Action 2023-07-19 04:49:27 +00:00
Crowdin Bot f6b3cc0c7c New Crowdin translations by Github Action 2023-07-19 04:46:55 +00:00
Hariom Balhara 902bb71273 Prefill logged in info (#10240) 2023-07-19 06:44:13 +02:00
db021cc696 fix: update list for countries that don't support alphanumeric sender ids (#10232)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-07-18 21:31:45 +00:00
Jaideep GuntupalliandUdit Takkar a2645c2ed4 feat: replaced slack icon with Discord (#10193)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-07-18 21:30:17 +00:00
Anik Dhabal Babu 1ec9a6924c feddback added (#10221) 2023-07-18 21:29:56 +00:00
Leo Giovanetti 09068b39e6 perf: Event-type config page (#10238) 2023-07-18 23:18:08 +02:00
Crowdin Bot 9069a2412d New Crowdin translations by Github Action 2023-07-18 20:30:45 +00:00
zomars 6b5c8935c5 fix: formatting 2023-07-18 13:27:54 -07:00
Crowdin Bot d27ff41682 New Crowdin translations by Github Action 2023-07-18 19:53:12 +00:00
Crowdin Bot c6ca736daa New Crowdin translations by Github Action 2023-07-18 19:50:00 +00:00
Carina WollendorferandCarinaWolli cedb2b72e9 fix: add missing booking paid webhook trigger to dropdwon (#10237)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-07-18 19:46:53 +00:00
Hariom Balhara 11081cb5d8 fix: Embed - Non transparent background when color-scheme of embedding document and cal.com iframe don't match (#10033)
## What does this PR do?

Fixes #10032

Before:
https://www.loom.com/share/1890e4eebf41426aaf66d8b4909d0765
After:
https://www.loom.com/share/8b00c41587f2467ab05ef48e4ed523ef


## Type of change

<!-- Please delete bullets that are not relevant. -->

- Bug fix (non-breaking change which fixes an issue)

## How should this be tested?

- See loom

## Mandatory Tasks

- [x] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

## Checklist
- I haven't added tests that prove my fix is effective or that my feature works
2023-07-18 09:46:35 -07:00
Hariom Balhara 34d65f67a9 fix: Avoid resetting state one every render. (#10210) 2023-07-18 16:42:40 +00:00
Keith Williams e4c49d0e0b fix: Added step to create env file for bundle analysis (#10224) 2023-07-18 09:20:17 -07:00
201 changed files with 7664 additions and 1784 deletions

No files matched your search

+6 -6
View File
@@ -22,18 +22,18 @@ Any other relevant information. For example, why do you consider this a bug and
### Actual Results ### Actual Results
- What's happening right now that is different from what is expected - What's happening right now that is different from what is expected
### Expected Results ### Expected Results
- This is an ideal result that the system should get after the tests are performed - This is an ideal result that the system should get after the tests are performed
### Technical details ### Technical details
- Browser version, screen recording, console logs, network requests: You can make a recording with [Bird Eats Bug](https://birdeatsbug.com/). - Browser version, screen recording, console logs, network requests: You can make a recording with [Bird Eats Bug](https://birdeatsbug.com/).
- Node.js version - Node.js version
- Anything else that you think could be an issue. - Anything else that you think could be an issue.
### Evidence ### Evidence
- How was this tested? This is quite mandatory in terms of bugs. Providing evidence of your testing with screenshots or/and videos is an amazing way to prove the bug and a troubleshooting chance to find the solution. - How was this tested? This is quite mandatory in terms of bugs. Providing evidence of your testing with screenshots or/and videos is an amazing way to prove the bug and a troubleshooting chance to find the solution.
+13 -12
View File
@@ -11,31 +11,32 @@ Fixes # (issue)
## Requirement/Documentation ## Requirement/Documentation
<!-- Please provide all documents that are important to understand the reason of that PR. --> <!-- Please provide all documents that are important to understand the reason of that PR. -->
- If there is a requirement document, please, share it here.
- If there is ab UI/UX design document, please, share it here. - If there is a requirement document, please, share it here.
- If there is ab UI/UX design document, please, share it here.
## Type of change ## Type of change
<!-- Please delete bullets that are not relevant. --> <!-- Please delete bullets that are not relevant. -->
- [ ] Bug fix (non-breaking change which fixes an issue) - [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Chore (refactoring code, technical debt, workflow improvements) - [ ] Chore (refactoring code, technical debt, workflow improvements)
- [ ] New feature (non-breaking change which adds functionality) - [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update - [ ] This change requires a documentation update
## How should this be tested? ## How should this be tested?
<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests --> <!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->
- Are there environment variables that should be set? - Are there environment variables that should be set?
- What are the minimal test data to have? - What are the minimal test data to have?
- What is expected (happy path) to have (input and output)? - What is expected (happy path) to have (input and output)?
- Any other important info that could help to test that PR - Any other important info that could help to test that PR
## Mandatory Tasks ## Mandatory Tasks
- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected. - [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.
## Checklist ## Checklist
@@ -7,8 +7,13 @@ on:
- main - main
jobs: jobs:
env:
name: Create env file
uses: ./.github/workflows/env-create-file.yml
secrets: inherit
build: build:
name: Production build name: Production build
needs: env
if: ${{ github.event_name == 'push' }} if: ${{ github.event_name == 'push' }}
uses: ./.github/workflows/production-build.yml uses: ./.github/workflows/production-build.yml
secrets: inherit secrets: inherit
-1
View File
@@ -90,7 +90,6 @@ That's where Cal.com comes in. Self-hosted or hosted by us. White-label by desig
- [Prisma.io](https://prisma.io/?ref=cal.com) - [Prisma.io](https://prisma.io/?ref=cal.com)
- [Daily.co](https://go.cal.com/daily) - [Daily.co](https://go.cal.com/daily)
## Contact us ## Contact us
Meet our sales team for any commercial inquiries. Meet our sales team for any commercial inquiries.
+1 -1
View File
@@ -1182,7 +1182,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
</div> </div>
</div> </div>
<div className="flex w-2/3 flex-col p-8"> <div className="flex w-2/3 flex-col p-8">
<HorizontalTabs data-testid="embed-tabs" tabs={parsedTabs} linkProps={{ shallow: true }} /> <HorizontalTabs data-testid="embed-tabs" tabs={parsedTabs} linkShallow />
{tabs.map((tab) => { {tabs.map((tab) => {
return ( return (
<div <div
+2 -4
View File
@@ -1,4 +1,3 @@
import { isEmpty } from "lodash";
import { useTranslation } from "next-i18next"; import { useTranslation } from "next-i18next";
import { useEffect } from "react"; import { useEffect } from "react";
@@ -20,13 +19,13 @@ export function useViewerI18n() {
/** /**
* Auto-switches locale client-side to the logged in user's preference * Auto-switches locale client-side to the logged in user's preference
*/ */
const I18nLanguageHandler = (): null => { const I18nLanguageHandler = () => {
const { i18n } = useTranslation("common"); const { i18n } = useTranslation("common");
const locale = useViewerI18n().data?.locale || i18n.language; const locale = useViewerI18n().data?.locale || i18n.language;
useEffect(() => { useEffect(() => {
// bail early when i18n = {} // bail early when i18n = {}
if (isEmpty(i18n)) return; if (Object.keys(i18n).length === 0) return;
// if locale is ready and the i18n.language does != locale - changeLanguage // if locale is ready and the i18n.language does != locale - changeLanguage
if (locale && i18n.language !== locale) { if (locale && i18n.language !== locale) {
i18n.changeLanguage(locale); i18n.changeLanguage(locale);
@@ -35,7 +34,6 @@ const I18nLanguageHandler = (): null => {
document.dir = i18n.dir(); document.dir = i18n.dir();
document.documentElement.setAttribute("lang", locale); document.documentElement.setAttribute("lang", locale);
}, [locale, i18n]); }, [locale, i18n]);
return null; return null;
}; };
+38 -37
View File
@@ -3,7 +3,7 @@ import type { IframeHTMLAttributes } from "react";
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { CAL_URL } from "@calcom/lib/constants"; import { CAL_URL } from "@calcom/lib/constants";
import type { RouterOutputs } from "@calcom/trpc/react"; import type { RouterOutputs } from "@calcom/trpc/react";
import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation"; import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation";
import { InstallAppButton, AppDependencyComponent } from "@calcom/app-store/components"; import { InstallAppButton, AppDependencyComponent } from "@calcom/app-store/components";
@@ -217,7 +217,7 @@ const Component = ({
}; };
} }
return ( return (
<InstallAppButtonChild appCategories={categories} userAdminTeams={appDbQuery.data?.userAdminTeams} addAppMutationInput={{type, variant, slug}} credentials={appDbQuery.data?.credentials} {...props} /> <InstallAppButtonChild appCategories={categories} userAdminTeams={appDbQuery.data?.userAdminTeams} addAppMutationInput={{ type, variant, slug }} credentials={appDbQuery.data?.credentials} {...props} />
); );
}} }}
/> />
@@ -444,49 +444,50 @@ const InstallAppButtonChild = ({
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuPortal> <DropdownMenuPortal>
<DropdownMenuContent <DropdownMenuContent
onInteractOutside={(event) => { onInteractOutside={(event) => {
if (mutation.isLoading) event.preventDefault(); if (mutation.isLoading) event.preventDefault();
}} }}
> >
{mutation.isLoading && ( {mutation.isLoading && (
<div className="z-1 fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"> <div className="z-1 fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
<Spinner /> <Spinner />
</div> </div>
)} )}
<DropdownMenuLabel>{t("install_app_on")}</DropdownMenuLabel> <DropdownMenuLabel>{t("install_app_on")}</DropdownMenuLabel>
{userAdminTeams.map((team) => { {userAdminTeams.map((team) => {
const isInstalled = credentials && const isInstalled = credentials &&
credentials.some((credential) => credentials.some((credential) =>
credential?.teamId ? credential?.teamId === team.id : credential.userId === team.id credential?.teamId ? credential?.teamId === team.id : credential.userId === team.id
) )
return ( return (
<DropdownItem <DropdownItem
type="button" type="button"
data-testid={team.isUser ? "install-app-button-personal" : "anything else"} data-testid={team.isUser ? "install-app-button-personal" : "anything else"}
key={team.id} key={team.id}
disabled={ disabled={
isInstalled isInstalled
} }
StartIcon={(props) => ( StartIcon={(props) => (
<Avatar <Avatar
alt={team.logo || ""} alt={team.logo || ""}
imageSrc={team.logo || `${CAL_URL}/${team.logo}/avatar.png`} // if no image, use default avatar imageSrc={team.logo || `${CAL_URL}/${team.logo}/avatar.png`} // if no image, use default avatar
size="sm" size="sm"
{...props} {...props}
/> />
)} )}
onClick={() => { onClick={() => {
mutation.mutate( mutation.mutate(
team.isUser ? addAppMutationInput : { ...addAppMutationInput, teamId: team.id } team.isUser ? addAppMutationInput : { ...addAppMutationInput, teamId: team.id }
); );
}}> }}>
<p>{team.name}{" "} <p>{team.name}{" "}
{isInstalled && {isInstalled &&
`(${t("installed")})`}</p> `(${t("installed")})`}</p>
</DropdownItem> </DropdownItem>
)})} )
})}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenuPortal> </DropdownMenuPortal>
</Dropdown> </Dropdown>
@@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
import { Controller, useFormContext } from "react-hook-form"; import { Controller, useFormContext } from "react-hook-form";
import short from "short-uuid"; import short from "short-uuid";
import { v5 as uuidv5 } from "uuid"; import { v5 as uuidv5 } from "uuid";
import { z } from "zod"; import type { z } from "zod";
import type { EventNameObjectType } from "@calcom/core/event"; import type { EventNameObjectType } from "@calcom/core/event";
import { getEventName } from "@calcom/core/event"; import { getEventName } from "@calcom/core/event";
@@ -17,14 +17,23 @@ import {
allowDisablingHostConfirmationEmails, allowDisablingHostConfirmationEmails,
} from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails"; } from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails";
import { FormBuilder } from "@calcom/features/form-builder/FormBuilder"; import { FormBuilder } from "@calcom/features/form-builder/FormBuilder";
import { EditableSchema } from "@calcom/features/form-builder/FormBuilderFieldsSchema" import type { EditableSchema } from "@calcom/features/form-builder/schema";
import { BookerLayoutSelector } from "@calcom/features/settings/BookerLayoutSelector"; import { BookerLayoutSelector } from "@calcom/features/settings/BookerLayoutSelector";
import { classNames } from "@calcom/lib"; import { classNames } from "@calcom/lib";
import { APP_NAME, CAL_URL } from "@calcom/lib/constants"; import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { Prisma } from "@calcom/prisma/client"; import type { Prisma } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import { Button, Checkbox, Label, SettingsToggle, showToast, TextField, Tooltip, Alert } from "@calcom/ui"; import {
Button,
CheckboxField,
Label,
SettingsToggle,
showToast,
TextField,
Tooltip,
Alert,
} from "@calcom/ui";
import { Edit, Copy } from "@calcom/ui/components/icon"; import { Edit, Copy } from "@calcom/ui/components/icon";
import RequiresConfirmationController from "./RequiresConfirmationController"; import RequiresConfirmationController from "./RequiresConfirmationController";
@@ -87,7 +96,9 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
return { return {
...field, ...field,
hidden: !enabled, hidden: !enabled,
editable: (!enabled ? "system-but-hidden" : "system-but-optional") as z.infer<typeof EditableSchema> editable: (!enabled ? "system-but-hidden" : "system-but-optional") as z.infer<
typeof EditableSchema
>,
}; };
} }
return field; return field;
@@ -340,7 +351,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
}} }}
/> />
<div className="mt-2"> <div className="mt-2">
<Checkbox <CheckboxField
description={t("show_attendees")} description={t("show_attendees")}
disabled={seatsLocked.disabled} disabled={seatsLocked.disabled}
onChange={(e) => formMethods.setValue("seatsShowAttendees", e.target.checked)} onChange={(e) => formMethods.setValue("seatsShowAttendees", e.target.checked)}
+16 -2
View File
@@ -1,3 +1,5 @@
import { Trans } from "next-i18next";
import Link from "next/link";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]"; import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { useFormContext } from "react-hook-form"; import { useFormContext } from "react-hook-form";
@@ -158,9 +160,21 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
{!shouldLockDisableProps("apps").disabled && ( {!shouldLockDisableProps("apps").disabled && (
<div className="bg-muted rounded-md p-8"> <div className="bg-muted rounded-md p-8">
{!isLoading && notInstalledApps?.length ? ( {!isLoading && notInstalledApps?.length ? (
<h2 className="text-emphasis text-lg font-semibold">{t("available_apps")}</h2> <>
<h2 className="text-emphasis mb-2 text-xl font-semibold leading-5 tracking-[0.01em]">
{t("available_apps_lower_case")}
</h2>
<p className="text-default mb-6 text-sm font-normal">
<Trans i18nKey="available_apps_desc">
You have no apps installed. View popular apps below and explore more in our &nbsp;
<Link className="cursor-pointer underline" href="/apps">
App Store
</Link>
</Trans>
</p>
</>
) : null} ) : null}
<div className="before:border-0"> <div className="bg-default border-subtle divide-subtle divide-y rounded-md border before:border-0">
{notInstalledApps?.map((app) => ( {notInstalledApps?.map((app) => (
<EventTypeAppCard <EventTypeAppCard
getAppData={getAppDataGetter(app.slug as EventTypeAppsList)} getAppData={getAppDataGetter(app.slug as EventTypeAppsList)}
@@ -1,5 +1,5 @@
import type { EventTypeSetup, FormValues } from "pages/event-types/[type]"; import type { EventTypeSetup, FormValues } from "pages/event-types/[type]";
import { useState } from "react"; import { useState, memo } from "react";
import { Controller, useFormContext } from "react-hook-form"; import { Controller, useFormContext } from "react-hook-form";
import type { OptionProps, SingleValueProps } from "react-select"; import type { OptionProps, SingleValueProps } from "react-select";
import { components } from "react-select"; import { components } from "react-select";
@@ -71,86 +71,91 @@ const format = (date: Date, hour12: boolean) =>
hourCycle: hour12 ? "h12" : "h24", hourCycle: hour12 ? "h12" : "h24",
}).format(new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss"))); }).format(new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss")));
const EventTypeScheduleDetails = ({ const EventTypeScheduleDetails = memo(
isManagedEventType, ({
selectedScheduleValue, isManagedEventType,
}: { selectedScheduleValue,
isManagedEventType: boolean; }: {
selectedScheduleValue: AvailabilityOption | undefined; isManagedEventType: boolean;
}) => { selectedScheduleValue: AvailabilityOption | undefined;
const { data: loggedInUser } = useMeQuery(); }) => {
const timeFormat = loggedInUser?.timeFormat; const { data: loggedInUser } = useMeQuery();
const { t, i18n } = useLocale(); const timeFormat = loggedInUser?.timeFormat;
const { watch } = useFormContext<FormValues>(); const { t, i18n } = useLocale();
const { watch } = useFormContext<FormValues>();
const scheduleId = watch("schedule"); const scheduleId = watch("schedule");
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery( const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
{ {
scheduleId: scheduleId || loggedInUser?.defaultScheduleId || selectedScheduleValue?.value || undefined, scheduleId:
isManagedEventType, scheduleId || loggedInUser?.defaultScheduleId || selectedScheduleValue?.value || undefined,
}, isManagedEventType,
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId || !!selectedScheduleValue } },
); { enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId || !!selectedScheduleValue }
);
const filterDays = (dayNum: number) => const filterDays = (dayNum: number) =>
schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || []; schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
return ( return (
<div className="border-default space-y-4 rounded border px-6 pb-4"> <div className="border-default space-y-4 rounded border px-6 pb-4">
<ol className="table border-collapse text-sm"> <ol className="table border-collapse text-sm">
{weekdayNames(i18n.language, 1, "long").map((day, index) => { {weekdayNames(i18n.language, 1, "long").map((day, index) => {
const isAvailable = !!filterDays(index).length; const isAvailable = !!filterDays(index).length;
return ( return (
<li key={day} className="my-6 flex border-transparent last:mb-2"> <li key={day} className="my-6 flex border-transparent last:mb-2">
<span <span
className={classNames( className={classNames(
"w-20 font-medium sm:w-32 ", "w-20 font-medium sm:w-32 ",
!isAvailable ? "text-subtle line-through" : "text-default" !isAvailable ? "text-subtle line-through" : "text-default"
)}> )}>
{day} {day}
</span> </span>
{isLoading ? ( {isLoading ? (
<SkeletonText className="block h-5 w-60" /> <SkeletonText className="block h-5 w-60" />
) : isAvailable ? ( ) : isAvailable ? (
<div className="space-y-3 text-right"> <div className="space-y-3 text-right">
{filterDays(index).map((dayRange, i) => ( {filterDays(index).map((dayRange, i) => (
<div key={i} className="text-default flex items-center leading-4"> <div key={i} className="text-default flex items-center leading-4">
<span className="w-16 sm:w-28 sm:text-left"> <span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)} {format(dayRange.startTime, timeFormat === 12)}
</span> </span>
<span className="ms-4">-</span> <span className="ms-4">-</span>
<div className="ml-6 sm:w-28">{format(dayRange.endTime, timeFormat === 12)}</div> <div className="ml-6 sm:w-28">{format(dayRange.endTime, timeFormat === 12)}</div>
</div> </div>
))} ))}
</div> </div>
) : ( ) : (
<span className="text-subtle ml-6 sm:ml-0">{t("unavailable")}</span> <span className="text-subtle ml-6 sm:ml-0">{t("unavailable")}</span>
)} )}
</li> </li>
); );
})} })}
</ol> </ol>
<hr className="border-subtle" /> <hr className="border-subtle" />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between"> <div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="text-default flex items-center justify-center text-sm sm:justify-start"> <span className="text-default flex items-center justify-center text-sm sm:justify-start">
<Globe className="h-3.5 w-3.5 ltr:mr-2 rtl:ml-2" /> <Globe className="h-3.5 w-3.5 ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />} {schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span> </span>
{!!schedule?.id && !schedule.isManaged && ( {!!schedule?.id && !schedule.isManaged && (
<Button <Button
href={`/availability/${schedule.id}`} href={`/availability/${schedule.id}`}
disabled={isLoading} disabled={isLoading}
color="minimal" color="minimal"
EndIcon={ExternalLink} EndIcon={ExternalLink}
target="_blank" target="_blank"
rel="noopener noreferrer"> rel="noopener noreferrer">
{t("edit_availability")} {t("edit_availability")}
</Button> </Button>
)} )}
</div>
</div> </div>
</div> );
); }
}; );
EventTypeScheduleDetails.displayName = "EventTypeScheduleDetails";
const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => { const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
const { t } = useLocale(); const { t } = useLocale();
+12 -7
View File
@@ -19,16 +19,17 @@ interface IUserToValue {
email: string; email: string;
} }
const mapUserToValue = ({ id, name, username, email }: IUserToValue) => ({ const mapUserToValue = ({ id, name, username, email }: IUserToValue, pendingString: string) => ({
value: `${id || ""}`, value: `${id || ""}`,
label: `${name || ""}`, label: `${name || email || ""}${!username ? ` (${pendingString})` : ""}`,
avatar: `${WEBAPP_URL}/${username}/avatar.png`, avatar: `${WEBAPP_URL}/${username}/avatar.png`,
email, email,
}); });
export const mapMemberToChildrenOption = ( export const mapMemberToChildrenOption = (
member: EventTypeSetupProps["teamMembers"][number], member: EventTypeSetupProps["teamMembers"][number],
slug: string slug: string,
pendingString: string
) => { ) => {
return { return {
slug, slug,
@@ -43,7 +44,7 @@ export const mapMemberToChildrenOption = (
eventTypeSlugs: member.eventTypes ?? [], eventTypeSlugs: member.eventTypes ?? [],
}, },
value: `${member.id ?? ""}`, value: `${member.id ?? ""}`,
label: member.name ?? "", label: `${member.name || member.email || ""}${!member.username ? ` (${pendingString})` : ""}`,
}; };
}; };
@@ -291,9 +292,13 @@ export const EventTeamTab = ({
// description: t("round_robin_description"), // description: t("round_robin_description"),
}, },
]; ];
const teamMembersOptions = teamMembers.map(mapUserToValue); const pendingMembers = (member: (typeof teamMembers)[number]) =>
const childrenEventTypeOptions = teamMembers.map((member) => { !!eventType.team?.parentId || !!member.username;
return mapMemberToChildrenOption(member, eventType.slug); const teamMembersOptions = teamMembers
.filter(pendingMembers)
.map((member) => mapUserToValue(member, t("pending")));
const childrenEventTypeOptions = teamMembers.filter(pendingMembers).map((member) => {
return mapMemberToChildrenOption(member, eventType.slug, t("pending"));
}); });
const isManagedEventType = eventType.schedulingType === SchedulingType.MANAGED; const isManagedEventType = eventType.schedulingType === SchedulingType.MANAGED;
return ( return (
@@ -407,13 +407,13 @@ function EventTypeSingleLayout({
className="primary-navigation" className="primary-navigation"
tabs={EventTypeTabs} tabs={EventTypeTabs}
sticky sticky
linkProps={{ shallow: true }} linkShallow
itemClassname="items-start" itemClassname="items-start"
iconClassName="md:mt-px" iconClassName="md:mt-px"
/> />
</div> </div>
<div className="p-2 md:mx-0 md:p-0 xl:hidden"> <div className="p-2 md:mx-0 md:p-0 xl:hidden">
<HorizontalTabs tabs={EventTypeTabs} linkProps={{ shallow: true }} /> <HorizontalTabs tabs={EventTypeTabs} linkShallow />
</div> </div>
<div className="w-full ltr:mr-2 rtl:ml-2"> <div className="w-full ltr:mr-2 rtl:ml-2">
<div <div
@@ -12,7 +12,7 @@ import TwoFactorAuthAPI from "./TwoFactorAuthAPI";
interface DisableTwoFactorAuthModalProps { interface DisableTwoFactorAuthModalProps {
open: boolean; open: boolean;
onOpenChange: () => void; onOpenChange: () => void;
disablePassword?: boolean;
/** Called when the user closes the modal without disabling two-factor auth */ /** Called when the user closes the modal without disabling two-factor auth */
onCancel: () => void; onCancel: () => void;
/** Called when the user disables two-factor auth */ /** Called when the user disables two-factor auth */
@@ -27,6 +27,7 @@ interface DisableTwoFactorValues {
const DisableTwoFactorAuthModal = ({ const DisableTwoFactorAuthModal = ({
onDisable, onDisable,
onCancel, onCancel,
disablePassword,
open, open,
onOpenChange, onOpenChange,
}: DisableTwoFactorAuthModalProps) => { }: DisableTwoFactorAuthModalProps) => {
@@ -75,19 +76,21 @@ const DisableTwoFactorAuthModal = ({
<DialogContent title={t("disable_2fa")} description={t("disable_2fa_recommendation")} type="creation"> <DialogContent title={t("disable_2fa")} description={t("disable_2fa_recommendation")} type="creation">
<Form form={form} handleSubmit={handleDisable}> <Form form={form} handleSubmit={handleDisable}>
<div className="mb-8"> <div className="mb-8">
<PasswordField {!disablePassword && (
labelProps={{ <PasswordField
className: "block text-sm font-medium text-default", labelProps={{
}} className: "block text-sm font-medium text-default",
{...form.register("password")} }}
className="border-default mt-1 block w-full rounded-md border px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-black" {...form.register("password")}
/> className="border-default mt-1 block w-full rounded-md border px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-black"
/>
)}
<TwoFactor center={false} /> <TwoFactor center={false} />
{errorMessage && <p className="mt-1 text-sm text-red-700">{errorMessage}</p>} {errorMessage && <p className="mt-1 text-sm text-red-700">{errorMessage}</p>}
</div> </div>
<DialogFooter showDivider className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse"> <DialogFooter showDivider className="relative mt-5">
<Button color="secondary" onClick={onCancel}> <Button color="secondary" onClick={onCancel}>
{t("cancel")} {t("cancel")}
</Button> </Button>
@@ -185,7 +185,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, open, onOpenChange }: Enable
)} )}
</div> </div>
</WithStep> </WithStep>
<DialogFooter className="mt-8 sm:flex sm:flex-row-reverse" showDivider> <DialogFooter className="mt-8" showDivider>
<Button color="secondary" onClick={onCancel}> <Button color="secondary" onClick={onCancel}>
{t("cancel")} {t("cancel")}
</Button> </Button>
+15 -2
View File
@@ -54,7 +54,12 @@ const getEmbedNamespace = (query: ReturnType<typeof useRouter>["query"]) => {
return typeof window !== "undefined" ? window.getEmbedNamespace() : (query.embed as string) || null; return typeof window !== "undefined" ? window.getEmbedNamespace() : (query.embed as string) || null;
}; };
const CustomI18nextProvider = (props: AppPropsWithChildren) => { // We dont need to pass nonce to the i18n provider - this was causing x2-x3 re-renders on a hard refresh
type AppPropsWithoutNonce = Omit<AppPropsWithChildren, "pageProps"> & {
pageProps: Omit<AppPropsWithChildren["pageProps"], "nonce">;
};
const CustomI18nextProvider = (props: AppPropsWithoutNonce) => {
/** /**
* i18n should never be clubbed with other queries, so that it's caching can be managed independently. * i18n should never be clubbed with other queries, so that it's caching can be managed independently.
* We intend to not cache i18n query * We intend to not cache i18n query
@@ -222,11 +227,19 @@ const AppProviders = (props: AppPropsWithChildren) => {
const session = trpc.viewer.public.session.useQuery().data; const session = trpc.viewer.public.session.useQuery().data;
// No need to have intercom on public pages - Good for Page Performance // No need to have intercom on public pages - Good for Page Performance
const isPublicPage = usePublicPage(); const isPublicPage = usePublicPage();
const { pageProps, ...rest } = props;
const { _nonce, ...restPageProps } = pageProps;
const propsWithoutNonce = {
pageProps: {
...restPageProps,
},
...rest,
};
const RemainingProviders = ( const RemainingProviders = (
<EventCollectionProvider options={{ apiPath: "/api/collect-events" }}> <EventCollectionProvider options={{ apiPath: "/api/collect-events" }}>
<SessionProvider session={session || undefined}> <SessionProvider session={session || undefined}>
<CustomI18nextProvider {...props}> <CustomI18nextProvider {...propsWithoutNonce}>
<TooltipProvider> <TooltipProvider>
{/* color-scheme makes background:transparent not work which is required by embed. We need to ensure next-theme adds color-scheme to `body` instead of `html`(https://github.com/pacocoursey/next-themes/blob/main/src/index.tsx#L74). Once that's done we can enable color-scheme support */} {/* color-scheme makes background:transparent not work which is required by embed. We need to ensure next-theme adds color-scheme to `body` instead of `html`(https://github.com/pacocoursey/next-themes/blob/main/src/index.tsx#L74). Once that's done we can enable color-scheme support */}
<CalcomThemeProvider <CalcomThemeProvider
+21
View File
@@ -446,6 +446,27 @@ const nextConfig = {
destination: "/apps/installed/conferencing", destination: "/apps/installed/conferencing",
permanent: true, permanent: true,
}, },
// OAuth callbacks when sent to localhost:3000(w would be expected) should be redirected to corresponding to WEBAPP_URL
...(process.env.NODE_ENV === "development" &&
// Safer to enable the redirect only when the user is opting to test out organizations
process.env.ORGANIZATIONS_ENABLED &&
// Prevent infinite redirect by checking that we aren't already on localhost
process.env.NEXT_PUBLIC_WEBAPP_URL !== "http://localhost:3000"
? [
{
has: [
{
type: "header",
key: "host",
value: "localhost:3000",
},
],
source: "/api/integrations/:args*",
destination: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/api/integrations/:args*`,
permanent: false,
},
]
: []),
]; ];
if (process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com") { if (process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com") {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@calcom/web", "name": "@calcom/web",
"version": "3.1.2", "version": "3.1.4",
"private": true, "private": true,
"scripts": { "scripts": {
"analyze": "ANALYZE=true next build", "analyze": "ANALYZE=true next build",
+4 -17
View File
@@ -1,13 +1,14 @@
import type { GetStaticPropsContext } from "next"; import type { GetStaticPropsContext } from "next";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { orgDomainConfig, subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains"; import { orgDomainConfig, subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains";
import { DOCS_URL, JOIN_DISCORD, WEBSITE_URL, IS_CALCOM } from "@calcom/lib/constants"; import { DOCS_URL, JOIN_DISCORD, WEBSITE_URL, IS_CALCOM } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HeadSeo } from "@calcom/ui"; import { HeadSeo } from "@calcom/ui";
import { BookOpen, Check, ChevronRight, FileText, Shield } from "@calcom/ui/components/icon"; import { BookOpen, Check, ChevronRight, FileText, Shield } from "@calcom/ui/components/icon";
import { Discord } from "@calcom/ui/components/icon/Discord";
import PageWrapper from "@components/PageWrapper"; import PageWrapper from "@components/PageWrapper";
@@ -205,14 +206,7 @@ export default function Custom404() {
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse"> className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg"> <span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg">
<svg <Discord className="text-default h-6 w-6" />
className="text-default h-6 w-6"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 127.14 96.36">
<title>Discord Logo</title>
<path d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z" />
</svg>
</span> </span>
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
@@ -350,14 +344,7 @@ export default function Custom404() {
className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse"> className="relative flex items-start space-x-4 py-6 rtl:space-x-reverse">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg"> <span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg">
<svg <Discord className="text-default h-6 w-6" />
className="text-default h-6 w-6"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 127.14 96.36">
<title>Discord Logo</title>
<path d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z" />
</svg>
</span> </span>
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
+4 -3
View File
@@ -28,17 +28,18 @@ class MyDocument extends Document<Props> {
// Use a dummy URL as default so that URL parsing works for relative URLs as well. We care about searchParams and pathname only // Use a dummy URL as default so that URL parsing works for relative URLs as well. We care about searchParams and pathname only
const parsedUrl = new URL(asPath, "https://dummyurl"); const parsedUrl = new URL(asPath, "https://dummyurl");
const isEmbed = parsedUrl.pathname.endsWith("/embed") || parsedUrl.searchParams.get("embedType") !== null; const isEmbed = parsedUrl.pathname.endsWith("/embed") || parsedUrl.searchParams.get("embedType") !== null;
const embedColorScheme = parsedUrl.searchParams.get("ui.color-scheme");
const initialProps = await Document.getInitialProps(ctx); const initialProps = await Document.getInitialProps(ctx);
return { isEmbed, nonce, ...initialProps }; return { isEmbed, embedColorScheme, nonce, ...initialProps };
} }
render() { render() {
const { locale } = this.props.__NEXT_DATA__; const { locale } = this.props.__NEXT_DATA__;
const { isEmbed } = this.props; const { isEmbed, embedColorScheme } = this.props;
const nonceParsed = z.string().safeParse(this.props.nonce); const nonceParsed = z.string().safeParse(this.props.nonce);
const nonce = nonceParsed.success ? nonceParsed.data : ""; const nonce = nonceParsed.success ? nonceParsed.data : "";
return ( return (
<Html lang={locale}> <Html lang={locale} style={embedColorScheme ? { colorScheme: embedColorScheme as string } : undefined}>
<Head nonce={nonce}> <Head nonce={nonce}>
<link rel="apple-touch-icon" sizes="180x180" href="/api/logo?type=apple-touch-icon" /> <link rel="apple-touch-icon" sizes="180x180" href="/api/logo?type=apple-touch-icon" />
<link rel="icon" type="image/png" sizes="32x32" href="/api/logo?type=favicon-32" /> <link rel="icon" type="image/png" sizes="32x32" href="/api/logo?type=favicon-32" />
+3 -1
View File
@@ -12,7 +12,9 @@ import { IdentityProvider } from "@calcom/prisma/enums";
import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
const signupSchema = z.object({ const signupSchema = z.object({
username: z.string(), username: z.string().refine((value) => !value.includes("+"), {
message: "String should not contain a plus symbol (+).",
}),
email: z.string().email(), email: z.string().email(),
password: z.string().min(7), password: z.string().min(7),
language: z.string().optional(), language: z.string().optional(),
@@ -6,6 +6,7 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { verifyPassword } from "@calcom/features/auth/lib/verifyPassword"; import { verifyPassword } from "@calcom/features/auth/lib/verifyPassword";
import { symmetricDecrypt } from "@calcom/lib/crypto"; import { symmetricDecrypt } from "@calcom/lib/crypto";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { IdentityProvider } from "@calcom/prisma/client";
export default async function handler(req: NextApiRequest, res: NextApiResponse) { export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") { if (req.method !== "POST") {
@@ -28,7 +29,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
return res.status(401).json({ message: "Not authenticated" }); return res.status(401).json({ message: "Not authenticated" });
} }
if (!user.password) { if (!user.password && user.identityProvider === IdentityProvider.CAL) {
return res.status(400).json({ error: ErrorCode.UserMissingPassword }); return res.status(400).json({ error: ErrorCode.UserMissingPassword });
} }
@@ -36,9 +37,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
return res.json({ message: "Two factor disabled" }); return res.json({ message: "Two factor disabled" });
} }
const isCorrectPassword = await verifyPassword(req.body.password, user.password); if (user.password && user.identityProvider === IdentityProvider.CAL) {
if (!isCorrectPassword) { const isCorrectPassword = await verifyPassword(req.body.password, user.password);
return res.status(400).json({ error: ErrorCode.IncorrectPassword }); if (!isCorrectPassword) {
return res.status(400).json({ error: ErrorCode.IncorrectPassword });
}
} }
// if user has 2fa // if user has 2fa
if (user.twoFactorEnabled) { if (user.twoFactorEnabled) {
+1 -1
View File
@@ -57,7 +57,7 @@ export default function Login({
.string() .string()
.min(1, `${t("error_required_field")}`) .min(1, `${t("error_required_field")}`)
.email(`${t("enter_valid_email")}`), .email(`${t("enter_valid_email")}`),
password: z.string().min(1, `${t("error_required_field")}`), password: !!totpEmail ? z.literal("") : z.string().min(1, `${t("error_required_field")}`),
}) })
// Passthrough other fields like totpCode // Passthrough other fields like totpCode
.passthrough(); .passthrough();
+5 -1
View File
@@ -279,7 +279,11 @@ export default function Availability() {
</Dropdown> </Dropdown>
<div className="border-default border-l-2" /> <div className="border-default border-l-2" />
<Button className="ml-4 lg:ml-0" type="submit" form="availability-form"> <Button
className="ml-4 lg:ml-0"
type="submit"
form="availability-form"
loading={updateMutation.isLoading}>
{t("save")} {t("save")}
</Button> </Button>
</div> </div>
+1 -1
View File
@@ -23,9 +23,9 @@ import {
useIsEmbed, useIsEmbed,
} from "@calcom/embed-core/embed-iframe"; } from "@calcom/embed-core/embed-iframe";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { SystemField } from "@calcom/features/bookings/lib/SystemField";
import { getBookingWithResponses } from "@calcom/features/bookings/lib/get-booking"; import { getBookingWithResponses } from "@calcom/features/bookings/lib/get-booking";
import { import {
SystemField,
getBookingFieldsWithSystemFields, getBookingFieldsWithSystemFields,
SMS_REMINDER_NUMBER_FIELD, SMS_REMINDER_NUMBER_FIELD,
} from "@calcom/features/bookings/lib/getBookingFields"; } from "@calcom/features/bookings/lib/getBookingFields";
+65 -58
View File
@@ -66,7 +66,6 @@ import {
User as UserIcon, User as UserIcon,
} from "@calcom/ui/components/icon"; } from "@calcom/ui/components/icon";
import { withQuery } from "@lib/QueryCell";
import useMeQuery from "@lib/hooks/useMeQuery"; import useMeQuery from "@lib/hooks/useMeQuery";
import { EmbedButton, EmbedDialog } from "@components/Embed"; import { EmbedButton, EmbedDialog } from "@components/Embed";
@@ -835,13 +834,76 @@ const SetupProfileBanner = ({ closeAction }: { closeAction: () => void }) => {
); );
}; };
const Main = () => {
const isMobile = useMediaQuery("(max-width: 768px)");
const router = useRouter();
const filters = getTeamsFiltersFromQuery(router.query);
const orgBranding = useOrgBrandingValues();
// TODO: Maybe useSuspenseQuery to focus on success case only? Remember that it would crash the page when there is an error in query. Also, it won't support skeleton
const res = trpc.viewer.eventTypes.getByViewer.useQuery(filters && { filters });
if (res.status === "loading") {
return <SkeletonLoader />;
}
if (res.status === "error") {
return <Alert severity="error" title="Something went wrong" message={res.error.message} />;
}
const data = res.data;
const isFilteredByOnlyOneItem =
(filters?.teamIds?.length === 1 || filters?.userIds?.length === 1) && data.eventTypeGroups.length === 1;
return (
<>
{data.eventTypeGroups.length > 1 || isFilteredByOnlyOneItem ? (
<>
{isMobile ? (
<MobileTeamsTab eventTypeGroups={data.eventTypeGroups} />
) : (
data.eventTypeGroups.map((group: EventTypeGroup, index: number) => (
<div className="flex flex-col" key={group.profile.slug}>
<EventTypeListHeading
profile={group.profile}
membershipCount={group.metadata.membershipCount}
teamId={group.teamId}
orgSlug={orgBranding?.slug}
/>
<EventTypeList
types={group.eventTypes}
group={group}
groupIndex={index}
readOnly={group.metadata.readOnly}
/>
</div>
))
)}
</>
) : (
data.eventTypeGroups.length === 1 && (
<EventTypeList
types={data.eventTypeGroups[0].eventTypes}
group={data.eventTypeGroups[0]}
groupIndex={0}
readOnly={data.eventTypeGroups[0].metadata.readOnly}
/>
)
)}
{data.eventTypeGroups.length === 0 && <CreateFirstEventTypeView />}
<EmbedDialog />
{router.query.dialog === "duplicate" && <DuplicateDialog />}
</>
);
};
const EventTypesPage = () => { const EventTypesPage = () => {
const { t } = useLocale(); const { t } = useLocale();
const router = useRouter(); const router = useRouter();
const { open } = useIntercom(); const { open } = useIntercom();
const { query } = router; const { query } = router;
const { data: user } = useMeQuery(); const { data: user } = useMeQuery();
const isMobile = useMediaQuery("(max-width: 768px)");
const [showProfileBanner, setShowProfileBanner] = useState(false); const [showProfileBanner, setShowProfileBanner] = useState(false);
const orgBranding = useOrgBrandingValues(); const orgBranding = useOrgBrandingValues();
@@ -860,10 +922,6 @@ const EventTypesPage = () => {
); );
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
const filters = getTeamsFiltersFromQuery(router.query);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const WithQuery = withQuery(trpc.viewer.eventTypes.getByViewer as any, filters && { filters });
return ( return (
<div> <div>
@@ -879,58 +937,7 @@ const EventTypesPage = () => {
afterHeading={showProfileBanner && <SetupProfileBanner closeAction={closeBanner} />} afterHeading={showProfileBanner && <SetupProfileBanner closeAction={closeBanner} />}
beforeCTAactions={<Actions />} beforeCTAactions={<Actions />}
CTA={<CTA />}> CTA={<CTA />}>
<WithQuery <Main />
customLoader={<SkeletonLoader />}
success={({ data }) => {
const isFilteredByOnlyOneItem =
(filters?.teamIds?.length === 1 || filters?.userIds?.length === 1) &&
data.eventTypeGroups.length === 1;
return (
<>
{data.eventTypeGroups.length > 1 || isFilteredByOnlyOneItem ? (
<>
{isMobile ? (
<MobileTeamsTab eventTypeGroups={data.eventTypeGroups} />
) : (
data.eventTypeGroups.map((group: EventTypeGroup, index: number) => (
<div className="flex flex-col" key={group.profile.slug}>
<EventTypeListHeading
profile={group.profile}
membershipCount={group.metadata.membershipCount}
teamId={group.teamId}
orgSlug={orgBranding?.slug}
/>
<EventTypeList
types={group.eventTypes}
group={group}
groupIndex={index}
readOnly={group.metadata.readOnly}
/>
</div>
))
)}
</>
) : (
data.eventTypeGroups.length === 1 && (
<EventTypeList
types={data.eventTypeGroups[0].eventTypes}
group={data.eventTypeGroups[0]}
groupIndex={0}
readOnly={data.eventTypeGroups[0].metadata.readOnly}
/>
)
)}
{data.eventTypeGroups.length === 0 && <CreateFirstEventTypeView />}
<EmbedDialog />
{router.query.dialog === "duplicate" && <DuplicateDialog />}
</>
);
}}
/>
</Shell> </Shell>
</div> </div>
); );
@@ -34,14 +34,15 @@ const TwoFactorAuthView = () => {
if (isLoading) return <SkeletonLoader />; if (isLoading) return <SkeletonLoader />;
const isCalProvider = user?.identityProvider === "CAL"; const isCalProvider = user?.identityProvider === "CAL";
const canSetupTwoFactor = !isCalProvider && !user?.twoFactorEnabled;
return ( return (
<> <>
<Meta title={t("2fa")} description={t("set_up_two_factor_authentication")} /> <Meta title={t("2fa")} description={t("set_up_two_factor_authentication")} />
{!isCalProvider && <Alert severity="neutral" message={t("2fa_disabled")} />} {canSetupTwoFactor && <Alert severity="neutral" message={t("2fa_disabled")} />}
<div className="mt-6 flex items-start space-x-4"> <div className="mt-6 flex items-start space-x-4">
<Switch <Switch
data-testid="two-factor-switch" data-testid="two-factor-switch"
disabled={!isCalProvider} disabled={canSetupTwoFactor}
checked={user?.twoFactorEnabled} checked={user?.twoFactorEnabled}
onCheckedChange={() => onCheckedChange={() =>
user?.twoFactorEnabled ? setDisableModalOpen(true) : setEnableModalOpen(true) user?.twoFactorEnabled ? setDisableModalOpen(true) : setEnableModalOpen(true)
@@ -72,6 +73,7 @@ const TwoFactorAuthView = () => {
<DisableTwoFactorModal <DisableTwoFactorModal
open={disableModalOpen} open={disableModalOpen}
disablePassword={!isCalProvider}
onOpenChange={() => setDisableModalOpen(!disableModalOpen)} onOpenChange={() => setDisableModalOpen(!disableModalOpen)}
onDisable={() => { onDisable={() => {
setDisableModalOpen(false); setDisableModalOpen(false);
+14 -7
View File
@@ -1,3 +1,4 @@
import { zodResolver } from "@hookform/resolvers/zod";
import type { GetServerSidePropsContext } from "next"; import type { GetServerSidePropsContext } from "next";
import { signIn } from "next-auth/react"; import { signIn } from "next-auth/react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@@ -23,13 +24,18 @@ import PageWrapper from "@components/PageWrapper";
import { IS_GOOGLE_LOGIN_ENABLED } from "../server/lib/constants"; import { IS_GOOGLE_LOGIN_ENABLED } from "../server/lib/constants";
import { ssrInit } from "../server/lib/ssr"; import { ssrInit } from "../server/lib/ssr";
type FormValues = { const signupSchema = z.object({
username: string; username: z.string().refine((value) => !value.includes("+"), {
email: string; message: "String should not contain a plus symbol (+).",
password: string; }),
apiError: string; email: z.string().email(),
token?: string; password: z.string().min(7),
}; language: z.string().optional(),
token: z.string().optional(),
apiError: z.string().optional(), // Needed to display API errors doesnt get passed to the API
});
type FormValues = z.infer<typeof signupSchema>;
type SignupProps = inferSSRProps<typeof getServerSideProps>; type SignupProps = inferSSRProps<typeof getServerSideProps>;
@@ -39,6 +45,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
const flags = useFlagMap(); const flags = useFlagMap();
const telemetry = useTelemetry(); const telemetry = useTelemetry();
const methods = useForm<FormValues>({ const methods = useForm<FormValues>({
resolver: zodResolver(signupSchema),
defaultValues: prepopulateFormValues, defaultValues: prepopulateFormValues,
}); });
const { const {
+10 -6
View File
@@ -130,7 +130,9 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
<div className="ms-3 inline-block truncate"> <div className="ms-3 inline-block truncate">
<span className="text-default text-sm font-bold">{ch.name}</span> <span className="text-default text-sm font-bold">{ch.name}</span>
<span className="text-subtle block text-xs"> <span className="text-subtle block text-xs">
{t("number_member", { count: ch.members.length })} {t("number_member", {
count: ch.members.filter((mem) => mem.user.username !== null).length,
})}
</span> </span>
</div> </div>
</div> </div>
@@ -138,11 +140,13 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
className="mr-6" className="mr-6"
size="sm" size="sm"
truncateAfter={4} truncateAfter={4}
items={ch.members.map(({ user: member }) => ({ items={ch.members
alt: member.name || "", .filter((mem) => mem.user.username !== null)
image: `/${member.username}/avatar.png`, .map(({ user: member }) => ({
title: member.name || "", alt: member.name || "",
}))} image: `/${member.username}/avatar.png`,
title: member.name || "",
}))}
/> />
</Link> </Link>
</li> </li>
+2 -3
View File
@@ -36,7 +36,6 @@ test.describe("2FA Tests", async () => {
*/ */
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await fillOtp({ page, secret: "123456", noRetry: true }); await fillOtp({ page, secret: "123456", noRetry: true });
await page.press('input[name="2fa6"]', "Enter");
await expect(page.locator('[data-testid="error-submitting-code"]')).toBeVisible(); await expect(page.locator('[data-testid="error-submitting-code"]')).toBeVisible();
await fillOtp({ await fillOtp({
@@ -44,9 +43,9 @@ test.describe("2FA Tests", async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
secret: secret!, secret: secret!,
}); });
await page.press('input[name="2fa6"]', "Enter");
await expect(page.locator(`[data-testid=two-factor-switch][data-state="checked"]`)).toBeVisible(); await page.waitForSelector(`[data-testid=two-factor-switch]`);
await expect(page.locator(`[data-testid=two-factor-switch]`).isChecked()).toBeTruthy();
return user; return user;
}); });
@@ -5,6 +5,7 @@ import { uuid } from "short-uuid";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { WebhookTriggerEvents } from "@calcom/prisma/enums"; import { WebhookTriggerEvents } from "@calcom/prisma/enums";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { test } from "./lib/fixtures"; import { test } from "./lib/fixtures";
import { createHttpServer, waitFor, selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils"; import { createHttpServer, waitFor, selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils";
@@ -40,6 +41,101 @@ test.describe("Manage Booking Questions", () => {
await runTestStepsCommonForTeamAndUserEventType(page, context, webhookReceiver); await runTestStepsCommonForTeamAndUserEventType(page, context, webhookReceiver);
}); });
test("Split 'Full name' into 'First name' and 'Last name'", async ({
page,
users,
context,
}, testInfo) => {
// Considering there are many steps in it, it would need more than default test timeout
test.setTimeout(testInfo.timeout * 3);
const user = await createAndLoginUserWithEventTypes({ page, users });
const webhookReceiver = await addWebhook(user);
await test.step("Go to first EventType Page ", async () => {
const $eventTypes = page.locator("[data-testid=event-types] > li a");
const firstEventTypeElement = $eventTypes.first();
await firstEventTypeElement.click();
});
await test.step("Open the 'Name' field dialog", async () => {
await page.click('[href$="tabName=advanced"]');
await page.locator('[data-testid="field-name"] [data-testid="edit-field-action"]').click();
});
await test.step("Toggle on the variant toggle and save Event Type", async () => {
await page.click('[data-testid="variant-toggle"]');
await page.click("[data-testid=field-add-save]");
await saveEventType(page);
});
await test.step("Book a time slot with firstName and lastName provided separately", async () => {
await doOnFreshPreview(page, context, async (page) => {
await expectSystemFieldsToBeThereOnBookingPage({ page, isFirstAndLastNameVariant: true });
await bookTimeSlot({
page,
name: { firstName: "John", lastName: "Doe" },
email: "booker@example.com",
});
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
expect(await page.locator('[data-testid="attendee-name-John Doe"]').nth(0).textContent()).toBe(
"John Doe"
);
await expectWebhookToBeCalled(webhookReceiver, {
triggerEvent: WebhookTriggerEvents.BOOKING_CREATED,
payload: {
attendees: [
{
// It would have full Name only
name: "John Doe",
email: "booker@example.com",
},
],
responses: {
name: {
label: "your_name",
value: {
firstName: "John",
lastName: "Doe",
},
},
email: {
label: "email_address",
value: "booker@example.com",
},
},
},
});
});
});
await test.step("Verify that we can prefill name and other fields correctly", async () => {
await doOnFreshPreview(page, context, async (page) => {
const url = page.url();
const prefillUrl = new URL(url);
prefillUrl.searchParams.append("name", "John Johny Janardan");
prefillUrl.searchParams.append("email", "john@example.com");
prefillUrl.searchParams.append("guests", "guest1@example.com");
prefillUrl.searchParams.append("guests", "guest2@example.com");
prefillUrl.searchParams.append("notes", "This is an additional note");
await page.goto(prefillUrl.toString());
await bookTimeSlot({ page, skipSubmission: true });
await expectSystemFieldsToBeThereOnBookingPage({
page,
isFirstAndLastNameVariant: true,
values: {
name: {
firstName: "John",
lastName: "Johny Janardan",
},
email: "john@example.com",
guests: ["guest1@example.com", "guest2@example.com"],
notes: "This is an additional note",
},
});
});
});
});
}); });
test.describe("For Team EventType", () => { test.describe("For Team EventType", () => {
@@ -91,12 +187,23 @@ async function runTestStepsCommonForTeamAndUserEventType(
} }
) { ) {
await page.click('[href$="tabName=advanced"]'); await page.click('[href$="tabName=advanced"]');
await test.step("Check that all the system questions are shown in the list", async () => {
await page.locator("[data-testid=field-name]").isVisible();
await page.locator("[data-testid=field-email]").isVisible();
await page.locator("[data-testid=field-notes]").isVisible();
await page.locator("[data-testid=field-guests]").isVisible();
await page.locator("[data-testid=field-rescheduleReason]").isVisible();
// It is conditional
// await page.locator("data-testid=field-location").isVisible();
});
await test.step("Add Question and see that it's shown on Booking Page at appropriate position", async () => { await test.step("Add Question and see that it's shown on Booking Page at appropriate position", async () => {
await addQuestionAndSave({ await addQuestionAndSave({
page, page,
question: { question: {
name: "how_are_you", name: "how_are_you",
type: "Name", type: "Address",
label: "How are you?", label: "How are you?",
placeholder: "I'm fine, thanks", placeholder: "I'm fine, thanks",
required: true, required: true,
@@ -104,13 +211,13 @@ async function runTestStepsCommonForTeamAndUserEventType(
}); });
await doOnFreshPreview(page, context, async (page) => { await doOnFreshPreview(page, context, async (page) => {
const allFieldsLocator = await expectSystemFieldsToBeThere(page); const allFieldsLocator = await expectSystemFieldsToBeThereOnBookingPage({ page });
const userFieldLocator = allFieldsLocator.nth(5); const userFieldLocator = allFieldsLocator.nth(5);
await expect(userFieldLocator.locator('[name="how_are_you"]')).toBeVisible(); await expect(userFieldLocator.locator('[name="how_are_you"]')).toBeVisible();
// There are 2 labels right now. Will be one in future. The second one is hidden // There are 2 labels right now. Will be one in future. The second one is hidden
expect(await getLabelText(userFieldLocator)).toBe("How are you?"); expect(await getLabelText(userFieldLocator)).toBe("How are you?");
await expect(userFieldLocator.locator("input[type=text]")).toBeVisible(); await expect(userFieldLocator.locator("input")).toBeVisible();
}); });
}); });
@@ -190,8 +297,6 @@ async function runTestStepsCommonForTeamAndUserEventType(
}, },
}); });
expect(payload.location).toBe("integrations:daily");
expect(payload.attendees[0]).toMatchObject({ expect(payload.attendees[0]).toMatchObject({
name: "Booker", name: "Booker",
email: "booker@example.com", email: "booker@example.com",
@@ -217,7 +322,24 @@ async function runTestStepsCommonForTeamAndUserEventType(
}); });
} }
async function expectSystemFieldsToBeThere(page: Page) { async function expectSystemFieldsToBeThereOnBookingPage({
page,
isFirstAndLastNameVariant,
values,
}: {
page: Page;
isFirstAndLastNameVariant?: boolean;
values?: Partial<{
name: {
firstName?: string;
lastName?: string;
fullName?: string;
};
email: string;
notes: string;
guests: string[];
}>;
}) {
const allFieldsLocator = page.locator("[data-fob-field-name]:not(.hidden)"); const allFieldsLocator = page.locator("[data-fob-field-name]:not(.hidden)");
const nameLocator = allFieldsLocator.nth(0); const nameLocator = allFieldsLocator.nth(0);
const emailLocator = allFieldsLocator.nth(1); const emailLocator = allFieldsLocator.nth(1);
@@ -226,11 +348,44 @@ async function expectSystemFieldsToBeThere(page: Page) {
const additionalNotes = allFieldsLocator.nth(3); const additionalNotes = allFieldsLocator.nth(3);
const guestsLocator = allFieldsLocator.nth(4); const guestsLocator = allFieldsLocator.nth(4);
await expect(nameLocator.locator('[name="name"]')).toBeVisible(); if (isFirstAndLastNameVariant) {
await expect(emailLocator.locator('[name="email"]')).toBeVisible(); if (values?.name) {
await expect(nameLocator.locator('[name="firstName"]')).toHaveValue(values?.name?.firstName || "");
await expect(nameLocator.locator('[name="lastName"]')).toHaveValue(values?.name?.lastName || "");
expect(await nameLocator.locator(".testid-firstName > label").innerText()).toContain("*");
} else {
await expect(nameLocator.locator('[name="firstName"]')).toBeVisible();
await expect(nameLocator.locator('[name="lastName"]')).toBeVisible();
}
} else {
if (values?.name) {
await expect(nameLocator.locator('[name="name"]')).toHaveValue(values?.name?.fullName || "");
}
await expect(nameLocator.locator('[name="name"]')).toBeVisible();
expect(await nameLocator.locator("label").innerText()).toContain("*");
}
await expect(additionalNotes.locator('[name="notes"]')).toBeVisible(); if (values?.email) {
await expect(guestsLocator.locator("button")).toBeVisible(); await expect(emailLocator.locator('[name="email"]')).toHaveValue(values?.email || "");
} else {
await expect(emailLocator.locator('[name="email"]')).toBeVisible();
}
if (values?.notes) {
await expect(additionalNotes.locator('[name="notes"]')).toHaveValue(values?.notes);
} else {
await expect(additionalNotes.locator('[name="notes"]')).toBeVisible();
}
if (values?.guests) {
const allGuestsLocators = guestsLocator.locator('[type="email"]');
for (let i = 0; i < values.guests.length; i++) {
await expect(allGuestsLocators.nth(i)).toHaveValue(values.guests[i] || "");
}
await expect(guestsLocator.locator("[data-testid='add-another-guest']")).toBeVisible();
} else {
await expect(guestsLocator.locator("[data-testid='add-guests']")).toBeVisible();
}
return allFieldsLocator; return allFieldsLocator;
} }
@@ -238,11 +393,33 @@ async function expectSystemFieldsToBeThere(page: Page) {
// Verify webhook is sent with the correct data, DB is correct (including metadata) // Verify webhook is sent with the correct data, DB is correct (including metadata)
//TODO: Verify that prefill works //TODO: Verify that prefill works
async function bookTimeSlot({ page, name, email }: { page: Page; name: string; email: string }) { async function bookTimeSlot({
// --- fill form page,
await page.fill('[name="name"]', name); name,
await page.fill('[name="email"]', email); email,
await page.press('[name="email"]', "Enter"); skipSubmission = false,
}: {
page: Page;
name?: string | { firstName: string; lastName?: string };
email?: string;
skipSubmission?: boolean;
}) {
if (name) {
if (typeof name === "string") {
await page.fill('[name="name"]', name);
} else {
await page.fill('[name="firstName"]', name.firstName);
if (name.lastName) {
await page.fill('[name="lastName"]', name.lastName);
}
}
}
if (email) {
await page.fill('[name="email"]', email);
}
if (!skipSubmission) {
await page.press('[name="email"]', "Enter");
}
} }
/** /**
@@ -424,3 +601,22 @@ async function addWebhook(
return webhookReceiver; return webhookReceiver;
} }
async function expectWebhookToBeCalled(
webhookReceiver: Awaited<ReturnType<typeof addWebhook>>,
expectedBody: {
triggerEvent: WebhookTriggerEvents;
payload: Omit<Partial<CalendarEvent>, "attendees"> & {
attendees: Partial<CalendarEvent["attendees"][number]>[];
};
}
) {
await waitFor(() => {
expect(webhookReceiver.requestList.length).toBe(1);
});
const [request] = webhookReceiver.requestList;
const body = request.body;
expect(body).toMatchObject(expectedBody);
}
+191 -1
View File
@@ -11,11 +11,23 @@
"calcom_explained_new_user": "Dokončete nastavení svého účtu {{appName}}! Jste jen několik kroků od vyřešení všech svých problémů s plánováním.", "calcom_explained_new_user": "Dokončete nastavení svého účtu {{appName}}! Jste jen několik kroků od vyřešení všech svých problémů s plánováním.",
"have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.", "have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.",
"reset_password_subject": "{{appName}}: Pokyny pro obnovení hesla", "reset_password_subject": "{{appName}}: Pokyny pro obnovení hesla",
"verify_email_subject": "{{appName}}: Ověřte svůj účet",
"check_your_email": "Zkontrolujte svůj e-mail",
"verify_email_page_body": "Odeslali jsme e-mail na adresu {{email}}. E-mailovou adresu je důležité ověřit, aby byla zaručena co nejlepší doručitelnost e-mailů a kalendářů z {{appName}}.",
"verify_email_banner_body": "Ověřte svoji e-mailovou adresu, abyste zaručili co nejlepší doručitelnost e-mailů a kalendáře",
"verify_email_email_header": "Ověřte svoji e-mailovou adresu",
"verify_email_email_button": "Ověřit e-mail",
"verify_email_email_body": "Ověřte svoji e-mailovou adresu kliknutím na tlačítko níže.",
"verify_email_email_link_text": "Zde je odkaz pro případ, že nemáte rádi klikání na tlačítka:",
"email_sent": "E-mail byl odeslán",
"event_declined_subject": "Odmítnuto: {{title}} v {{date}}", "event_declined_subject": "Odmítnuto: {{title}} v {{date}}",
"event_cancelled_subject": "Zrušeno: {{title}} ({{date}})",
"event_request_declined": "Žádost o událost byla zamítnuta", "event_request_declined": "Žádost o událost byla zamítnuta",
"event_request_declined_recurring": "Žádost o opakovanou událost byla zamítnuta", "event_request_declined_recurring": "Žádost o opakovanou událost byla zamítnuta",
"event_request_cancelled": "Vaše plánovaná událost byla zrušena",
"organizer": "Organizátor", "organizer": "Organizátor",
"need_to_reschedule_or_cancel": "Přeplánovat nebo zrušit?", "need_to_reschedule_or_cancel": "Přeplánovat nebo zrušit?",
"no_options_available": "Nejsou k dispozici žádné možnosti",
"cancellation_reason": "Důvod zrušení", "cancellation_reason": "Důvod zrušení",
"cancellation_reason_placeholder": "Proč rušíte?\n", "cancellation_reason_placeholder": "Proč rušíte?\n",
"rejection_reason": "Důvod odmítnutí", "rejection_reason": "Důvod odmítnutí",
@@ -75,7 +87,9 @@
"your_meeting_has_been_booked": "Vaše schůzka byla rezervována", "your_meeting_has_been_booked": "Vaše schůzka byla rezervována",
"event_type_has_been_rescheduled_on_time_date": "Váš {{title}} byl přeplánován na {{date}}.", "event_type_has_been_rescheduled_on_time_date": "Váš {{title}} byl přeplánován na {{date}}.",
"event_has_been_rescheduled": "Změna - Vaše událost byla přesunuta na jindy", "event_has_been_rescheduled": "Změna - Vaše událost byla přesunuta na jindy",
"request_reschedule_subtitle": "{{organizer}} zrušil rezervaci a požádal vás, abyste si vybrali jiný termín.",
"request_reschedule_title_organizer": "Požádali jste uživatele {{attendee}} o změnu časového plánu", "request_reschedule_title_organizer": "Požádali jste uživatele {{attendee}} o změnu časového plánu",
"request_reschedule_subtitle_organizer": "Zrušili jste rezervaci a účastník {{attendee}} by si s vámi měl rezervovat nový čas.",
"rescheduled_event_type_subject": "Žádost o přesunutí schůzky: {{eventType}} s {{name}} dne {{date}}", "rescheduled_event_type_subject": "Žádost o přesunutí schůzky: {{eventType}} s {{name}} dne {{date}}",
"requested_to_reschedule_subject_attendee": "Akce vyžadovaná k přeplánování: zarezervujte si nový čas pro událost {{eventType}} s osobou {{name}}", "requested_to_reschedule_subject_attendee": "Akce vyžadovaná k přeplánování: zarezervujte si nový čas pro událost {{eventType}} s osobou {{name}}",
"hi_user_name": "Hezký den, {{name}}", "hi_user_name": "Hezký den, {{name}}",
@@ -104,6 +118,7 @@
"team_info": "Informace o týmu", "team_info": "Informace o týmu",
"request_another_invitation_email": "Pokud si nepřejete použít e-mail {{toEmail}} pro {{appName}} nebo už účet na {{appName}} máte, požádejte prosím o další pozvánku na jiný e-mail.", "request_another_invitation_email": "Pokud si nepřejete použít e-mail {{toEmail}} pro {{appName}} nebo už účet na {{appName}} máte, požádejte prosím o další pozvánku na jiný e-mail.",
"you_have_been_invited": "Byli jste pozváni do týmu {{teamName}}", "you_have_been_invited": "Byli jste pozváni do týmu {{teamName}}",
"user_invited_you": "Uživatel {{user}} vás pozval, abyste se připojili k subjektu {{entity}} {{team}} v aplikaci {{appName}}",
"hidden_team_member_title": "V tomto týmu nejste viditelní", "hidden_team_member_title": "V tomto týmu nejste viditelní",
"hidden_team_member_message": "Vaše místo není zaplacené. Buď přejděte na tarif Pro, nebo informujte vlastníka týmu, že za vaše místo může zaplatit.", "hidden_team_member_message": "Vaše místo není zaplacené. Buď přejděte na tarif Pro, nebo informujte vlastníka týmu, že za vaše místo může zaplatit.",
"hidden_team_owner_message": "Pro využívání týmů potřebujete tarif Pro, budete skrytí, než přejdete na vyšší verzi.", "hidden_team_owner_message": "Pro využívání týmů potřebujete tarif Pro, budete skrytí, než přejdete na vyšší verzi.",
@@ -114,6 +129,8 @@
"team_upgrade_banner_description": "Děkujeme vám za vyzkoušení našeho nového týmového plánu. Všimli jsme si, že váš tým „{{teamName}}“ je nutné upgradovat.", "team_upgrade_banner_description": "Děkujeme vám za vyzkoušení našeho nového týmového plánu. Všimli jsme si, že váš tým „{{teamName}}“ je nutné upgradovat.",
"upgrade_banner_action": "Upgradovat zde", "upgrade_banner_action": "Upgradovat zde",
"team_upgraded_successfully": "Váš tým byl úspěšně přešel na vyšší verzi!", "team_upgraded_successfully": "Váš tým byl úspěšně přešel na vyšší verzi!",
"org_upgrade_banner_description": "Děkujeme, že jste vyzkoušeli tarif naší organizace. Všimli jsme si, že vaše organizace „{{teamName}}“ vyžaduje upgrade.",
"org_upgraded_successfully": "Vaše organizace byla upgradována!",
"use_link_to_reset_password": "Pro obnovení hesla použijte odkaz níž", "use_link_to_reset_password": "Pro obnovení hesla použijte odkaz níž",
"hey_there": "Zdravíme,", "hey_there": "Zdravíme,",
"forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}", "forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}",
@@ -180,6 +197,7 @@
"blog": "Blog", "blog": "Blog",
"blog_description": "Přečtěte si naše nejnovější novinky a články", "blog_description": "Přečtěte si naše nejnovější novinky a články",
"join_our_community": "Připojte se k naší komunitě", "join_our_community": "Připojte se k naší komunitě",
"join_our_discord": "Připojte se k našemu Discordu",
"404_claim_entity_user": "Nárokujte si své uživatelské jméno a plánujte události", "404_claim_entity_user": "Nárokujte si své uživatelské jméno a plánujte události",
"popular_pages": "Oblíbené stránky", "popular_pages": "Oblíbené stránky",
"register_now": "Zaregistrovat se nyní", "register_now": "Zaregistrovat se nyní",
@@ -187,6 +205,7 @@
"page_doesnt_exist": "Tato stránka neexistuje.", "page_doesnt_exist": "Tato stránka neexistuje.",
"check_spelling_mistakes_or_go_back": "Zkontrolovat chyby pravopisu nebo se vrátit na předchozí stránku.", "check_spelling_mistakes_or_go_back": "Zkontrolovat chyby pravopisu nebo se vrátit na předchozí stránku.",
"404_page_not_found": "404: Tato stránka nebyla nalezena.", "404_page_not_found": "404: Tato stránka nebyla nalezena.",
"booker_event_not_found": "Nepodařilo se nám najít událost, kterou se snažíte rezervovat.",
"getting_started": "Začínáme", "getting_started": "Začínáme",
"15min_meeting": "15 min schůzka", "15min_meeting": "15 min schůzka",
"30min_meeting": "30 min schůzka", "30min_meeting": "30 min schůzka",
@@ -222,11 +241,14 @@
"done": "Hotovo", "done": "Hotovo",
"all_done": "Hotovo!", "all_done": "Hotovo!",
"all": "Všechny aplikace", "all": "Všechny aplikace",
"yours": "Váš účet",
"available_apps": "Dostupné aplikace", "available_apps": "Dostupné aplikace",
"check_email_reset_password": "Podívejte se do e-mailu. Poslali jsme vám odkaz pro obnovení hesla.", "check_email_reset_password": "Podívejte se do e-mailu. Poslali jsme vám odkaz pro obnovení hesla.",
"finish": "Dokončit", "finish": "Dokončit",
"organization_general_description": "Správa nastavení jazyka a časového pásma vašeho týmu",
"few_sentences_about_yourself": "Pár vět o vás. Budou se zobrazovat na URL vaší osobní stránky.", "few_sentences_about_yourself": "Pár vět o vás. Budou se zobrazovat na URL vaší osobní stránky.",
"nearly_there": "Téměř hotovo!", "nearly_there": "Téměř hotovo!",
"nearly_there_instructions": "Poslední věc... stručný popis o vás a fotografie vám pomůžou získat rezervace a lidi aspoň budou vědět, koho si rezervují.",
"set_availability_instructions": "Určete si časové intervaly, kdy jste pravidelně dostupní. Později můžete vytvořit další a přiřadit je různým kalendářům.", "set_availability_instructions": "Určete si časové intervaly, kdy jste pravidelně dostupní. Později můžete vytvořit další a přiřadit je různým kalendářům.",
"set_availability": "Nastavte, jak jste dostupní", "set_availability": "Nastavte, jak jste dostupní",
"continue_without_calendar": "Pokračovat bez kalendáře", "continue_without_calendar": "Pokračovat bez kalendáře",
@@ -282,6 +304,18 @@
"success": "Povedlo se", "success": "Povedlo se",
"failed": "Nezdařilo se", "failed": "Nezdařilo se",
"password_has_been_reset_login": "Vaše heslo bylo obnoveno. Nyní se můžete přihlásit pomocí nově vytvořeného hesla.", "password_has_been_reset_login": "Vaše heslo bylo obnoveno. Nyní se můžete přihlásit pomocí nově vytvořeného hesla.",
"layout": "Rozvržení",
"bookerlayout_default_title": "Výchozí zobrazení",
"bookerlayout_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat.",
"bookerlayout_user_settings_title": "Rozvržení rezervace",
"bookerlayout_user_settings_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat. Lze nadefinovat pro každou událost zvlášť.",
"bookerlayout_month_view": "Měsíční",
"bookerlayout_week_view": "Týdenní",
"bookerlayout_column_view": "Sloupec",
"bookerlayout_error_min_one_enabled": "Musí být povoleno alespoň jedno rozvržení.",
"bookerlayout_error_default_not_enabled": "Rozvržení, které jste vybrali jako výchozí zobrazení, není součástí povolených rozvržení.",
"bookerlayout_error_unknown_layout": "Vámi vybrané rozvržení není platné rozvržení.",
"bookerlayout_override_global_settings": "Tohle lze nastavit pro všechny typy událostí v <2>nastavení / vzhledu</2> nebo <6>nadefinovat pouze pro tuto událost</6>.",
"unexpected_error_try_again": "Došlo k neočekávané chybě. Zkuste to znovu.", "unexpected_error_try_again": "Došlo k neočekávané chybě. Zkuste to znovu.",
"sunday_time_error": "Neplatný čas v neděli", "sunday_time_error": "Neplatný čas v neděli",
"monday_time_error": "Neplatný čas v pondělí", "monday_time_error": "Neplatný čas v pondělí",
@@ -294,6 +328,7 @@
"error_end_time_next_day": "Čas konce nemůže být delší než 24 hodin", "error_end_time_next_day": "Čas konce nemůže být delší než 24 hodin",
"back_to_bookings": "Zpět na rezervace", "back_to_bookings": "Zpět na rezervace",
"free_to_pick_another_event_type": "Kdykoliv si můžete vybrat jinou událost.", "free_to_pick_another_event_type": "Kdykoliv si můžete vybrat jinou událost.",
"cancelled": "Zrušeno",
"cancellation_successful": "Zrušení proběhlo úspěšně", "cancellation_successful": "Zrušení proběhlo úspěšně",
"really_cancel_booking": "Opravdu chcete zrušit svou rezervaci?", "really_cancel_booking": "Opravdu chcete zrušit svou rezervaci?",
"cannot_cancel_booking": "Tuto rezervaci nelze zrušit", "cannot_cancel_booking": "Tuto rezervaci nelze zrušit",
@@ -302,6 +337,12 @@
"cancelling_event_recurring": "Tato událost je jedním z případů opakující se události.", "cancelling_event_recurring": "Tato událost je jedním z případů opakující se události.",
"cancelling_all_recurring": "Toto jsou všechny zbývající instance opakující se události.", "cancelling_all_recurring": "Toto jsou všechny zbývající instance opakující se události.",
"error_with_status_code_occured": "Došlo k chybě se stavovým kódem {{status}}.", "error_with_status_code_occured": "Došlo k chybě se stavovým kódem {{status}}.",
"error_event_type_url_duplicate": "Typ události s touto adresou URL již existuje.",
"error_event_type_unauthorized_create": "Tuto událost nelze vytvořit",
"error_event_type_unauthorized_update": "Tuto událost nelze upravit",
"error_workflow_unauthorized_create": "Tento pracovní postup nelze vytvořit",
"error_schedule_unauthorized_create": "Nejste schopni vytvořit tento plán",
"booking_already_cancelled": "Tato rezervace již byla zrušena",
"booking_already_accepted_rejected": "Tato rezervace již byla přijata nebo zamítnuta", "booking_already_accepted_rejected": "Tato rezervace již byla přijata nebo zamítnuta",
"go_back_home": "Přejít na úvod", "go_back_home": "Přejít na úvod",
"or_go_back_home": "Nebo přejít na úvod", "or_go_back_home": "Nebo přejít na úvod",
@@ -311,10 +352,12 @@
"no_status_bookings_yet_description": "Nemáte žádné {{status}} rezervace. {{description}}", "no_status_bookings_yet_description": "Nemáte žádné {{status}} rezervace. {{description}}",
"event_between_users": "{{eventName}} mezi {{host}} a {{attendeeName}}", "event_between_users": "{{eventName}} mezi {{host}} a {{attendeeName}}",
"bookings": "Rezervace", "bookings": "Rezervace",
"booking_not_found": "Rezervace nenalezena",
"bookings_description": "Zobrazte si nadcházející a proběhlé události rezervovaní prostřednictvím odkazu na typ události.", "bookings_description": "Zobrazte si nadcházející a proběhlé události rezervovaní prostřednictvím odkazu na typ události.",
"upcoming_bookings": "Jakmile si někdo rezervuje váš čas, zobrazí se to zde.", "upcoming_bookings": "Jakmile si někdo rezervuje váš čas, zobrazí se to zde.",
"recurring_bookings": "Jakmile si někdo s vámi zarezervuje opakovanou schůzku, zobrazí se to zde.", "recurring_bookings": "Jakmile si někdo s vámi zarezervuje opakovanou schůzku, zobrazí se to zde.",
"past_bookings": "Vaše proběhlé rezervace se zobrazí zde.", "past_bookings": "Vaše proběhlé rezervace se zobrazí zde.",
"cancelled_bookings": "Zde se zobrazují vaše zrušené rezervace.",
"unconfirmed_bookings": "Vaše nepotvrzené rezervace se zobrazí zde.", "unconfirmed_bookings": "Vaše nepotvrzené rezervace se zobrazí zde.",
"unconfirmed_bookings_tooltip": "Nepotvrzené rezervace", "unconfirmed_bookings_tooltip": "Nepotvrzené rezervace",
"on": "dne", "on": "dne",
@@ -348,15 +391,19 @@
"user_dynamic_booking_disabled": "Někteří uživatelé ve skupině mají v současné době zakázané dynamické skupinové rezervace", "user_dynamic_booking_disabled": "Někteří uživatelé ve skupině mají v současné době zakázané dynamické skupinové rezervace",
"allow_dynamic_booking_tooltip": "Odkazy na skupinové rezervace, které lze vytvořit dynamicky přidáním více uživatelských jmen s „+“. příklad: „{{appName}}/bailey+peer“", "allow_dynamic_booking_tooltip": "Odkazy na skupinové rezervace, které lze vytvořit dynamicky přidáním více uživatelských jmen s „+“. příklad: „{{appName}}/bailey+peer“",
"allow_dynamic_booking": "Povolit účastníkům rezervovat vás prostřednictvím dynamických skupinových rezervací", "allow_dynamic_booking": "Povolit účastníkům rezervovat vás prostřednictvím dynamických skupinových rezervací",
"dynamic_booking": "Dynamické odkazy na skupiny",
"email": "E-mailová adresa", "email": "E-mailová adresa",
"email_placeholder": "vas@email.cz", "email_placeholder": "vas@email.cz",
"full_name": "Jméno a příjmení", "full_name": "Jméno a příjmení",
"browse_api_documentation": "Procházejte naši API dokumentaci", "browse_api_documentation": "Procházejte naši API dokumentaci",
"leverage_our_api": "Pro plnou kontrolu a přizpůsobení využijte naše API.", "leverage_our_api": "Pro plnou kontrolu a přizpůsobení využijte naše API.",
"create_webhook": "Vytvořit webhook", "create_webhook": "Vytvořit webhook",
"booking_cancelled": "Rezervace zrušena",
"booking_rescheduled": "Rezervace přesunuta", "booking_rescheduled": "Rezervace přesunuta",
"recording_ready": "Odkaz ke stažení záznamu je připraven", "recording_ready": "Odkaz ke stažení záznamu je připraven",
"booking_created": "Rezervace vytvořena", "booking_created": "Rezervace vytvořena",
"booking_rejected": "Rezervace zamítnuta",
"booking_requested": "Rezervace vyžádána",
"meeting_ended": "Schůzka skončila", "meeting_ended": "Schůzka skončila",
"form_submitted": "Formulář byl odeslán", "form_submitted": "Formulář byl odeslán",
"event_triggers": "Eventy na základě akce", "event_triggers": "Eventy na základě akce",
@@ -366,6 +413,8 @@
"team_webhooks": "Týmové Webhooky", "team_webhooks": "Týmové Webhooky",
"create_new_webhook_to_account": "Vytvořit nový webhook pro váš účet", "create_new_webhook_to_account": "Vytvořit nový webhook pro váš účet",
"new_webhook": "Nový webhook", "new_webhook": "Nový webhook",
"receive_cal_meeting_data": "Nechte si zaslat data o schůzce v {{appName}} na zadanou adresu URL v reálném čase, pokud dojde k naplánování nebo zrušení schůzky.",
"receive_cal_event_meeting_data": "Nechte si zaslat data o schůzce v {{appName}} na zadanou adresu URL v reálném čase, pokud dojde k naplánování nebo zrušení této schůzky.",
"responsive_fullscreen_iframe": "Responzivní iframe na celou obrazovku", "responsive_fullscreen_iframe": "Responzivní iframe na celou obrazovku",
"loading": "Načítám...", "loading": "Načítám...",
"deleting": "Odstraňování...", "deleting": "Odstraňování...",
@@ -428,6 +477,7 @@
"max_limit_allowed_hint": "Maximální povolená délka je {{limit}} znaků", "max_limit_allowed_hint": "Maximální povolená délka je {{limit}} znaků",
"invalid_password_hint": "Heslo musí být minimálně {{passwordLength}} znaků dlouhé, obsahovat alespoň jedno číslo a obsahovat kombinaci velkých a malých písmen", "invalid_password_hint": "Heslo musí být minimálně {{passwordLength}} znaků dlouhé, obsahovat alespoň jedno číslo a obsahovat kombinaci velkých a malých písmen",
"incorrect_password": "Heslo není správné.", "incorrect_password": "Heslo není správné.",
"incorrect_email_password": "E-mail nebo heslo jsou nesprávné.",
"use_setting": "Použít nastavení", "use_setting": "Použít nastavení",
"am_pm": "am/pm", "am_pm": "am/pm",
"time_options": "Nastavení času", "time_options": "Nastavení času",
@@ -455,6 +505,7 @@
"additional_guests": "Přidat hosty", "additional_guests": "Přidat hosty",
"your_name": "Vaše jméno", "your_name": "Vaše jméno",
"your_full_name": "Vaše celé jméno", "your_full_name": "Vaše celé jméno",
"no_name": "Žádné jméno",
"email_address": "E-mailová adresa", "email_address": "E-mailová adresa",
"enter_valid_email": "Zadejte platný e-mail", "enter_valid_email": "Zadejte platný e-mail",
"location": "Místo", "location": "Místo",
@@ -498,10 +549,13 @@
"your_team_updated_successfully": "Váš tým byl úspěšně aktualizován.", "your_team_updated_successfully": "Váš tým byl úspěšně aktualizován.",
"about": "O aplikaci", "about": "O aplikaci",
"team_description": "Pár vět o vašem týmu. Objeví se na URL stránce vašeho týmu.", "team_description": "Pár vět o vašem týmu. Objeví se na URL stránce vašeho týmu.",
"org_description": "Několik vět o vaší organizaci. Zobrazí se na adrese URL vaší organizace.",
"members": "Členové", "members": "Členové",
"organization_members": "Členové organizace",
"member": "Člen", "member": "Člen",
"number_member_one": "Počet členů: {{count}}", "number_member_one": "Počet členů: {{count}}",
"number_member_other": "Počet členů: {{count}}", "number_member_other": "Počet členů: {{count}}",
"number_selected": "Vybráno: {{count}}",
"owner": "Vlastník", "owner": "Vlastník",
"admin": "Administrátor", "admin": "Administrátor",
"administrator_user": "Uživatel administrátor", "administrator_user": "Uživatel administrátor",
@@ -532,6 +586,8 @@
"confirm_all": "Potvrdit vše", "confirm_all": "Potvrdit vše",
"disband_team": "Rozpustit tým", "disband_team": "Rozpustit tým",
"disband_team_confirmation_message": "Opravdu chcete rozpustit tento tým? Všichni, kterým jste tento týmový odkaz poslali, ho nebudou moct dál používat pro rezervace.", "disband_team_confirmation_message": "Opravdu chcete rozpustit tento tým? Všichni, kterým jste tento týmový odkaz poslali, ho nebudou moct dál používat pro rezervace.",
"disband_org": "Rozpustit organizaci",
"disband_org_confirmation_message": "Opravdu chcete tuto organizaci rozpustit? Všechny týmy a členové budou odstraněni.",
"remove_member_confirmation_message": "Opravdu chcete odstranit tohoto člena z týmu?", "remove_member_confirmation_message": "Opravdu chcete odstranit tohoto člena z týmu?",
"confirm_disband_team": "Ano, rozpustit tým", "confirm_disband_team": "Ano, rozpustit tým",
"confirm_remove_member": "Ano, odebrat člena", "confirm_remove_member": "Ano, odebrat člena",
@@ -606,6 +662,7 @@
"event_type_updated_successfully": "Typ události {{eventTypeTitle}} byl úspěšně aktualizován", "event_type_updated_successfully": "Typ události {{eventTypeTitle}} byl úspěšně aktualizován",
"event_type_deleted_successfully": "Typ události byl úspěšně smazán", "event_type_deleted_successfully": "Typ události byl úspěšně smazán",
"hours": "Hodiny", "hours": "Hodiny",
"people": "Lidé",
"your_email": "Váš e-mail", "your_email": "Váš e-mail",
"change_avatar": "Změnit avatar", "change_avatar": "Změnit avatar",
"language": "Jazyk", "language": "Jazyk",
@@ -638,9 +695,11 @@
"create_new_team": "Vytvořit nový tým", "create_new_team": "Vytvořit nový tým",
"open_invitations": "Otevřené pozvánky", "open_invitations": "Otevřené pozvánky",
"new_team": "Nový tým", "new_team": "Nový tým",
"create_first_team_and_invite_others": "Vytvořte svůj první tým a pozvěte ostatní uživatele ke spolupráci.",
"create_team_to_get_started": "Začněte vytvořením týmu", "create_team_to_get_started": "Začněte vytvořením týmu",
"teams": "Týmy", "teams": "Týmy",
"team": "Tým", "team": "Tým",
"organization": "Organizace",
"team_billing": "Fakturace týmů", "team_billing": "Fakturace týmů",
"team_billing_description": "Správa účtování pro váš tým", "team_billing_description": "Správa účtování pro váš tým",
"upgrade_to_flexible_pro_title": "Změnili jsme fakturaci pro týmy", "upgrade_to_flexible_pro_title": "Změnili jsme fakturaci pro týmy",
@@ -715,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}} poskytne URL Huddle01 web3 video meetingu.", "cal_provide_huddle01_meeting_url": "{{appName}} poskytne URL Huddle01 web3 video meetingu.",
"cal_provide_teams_meeting_url": "{{appName}} poskytne URL schůzky aplikace MS Teams. POZNÁMKA: MUSÍ SE JEDNAT O PRACOVNÍ NEBO ŠKOLNÍ ÚČET", "cal_provide_teams_meeting_url": "{{appName}} poskytne URL schůzky aplikace MS Teams. POZNÁMKA: MUSÍ SE JEDNAT O PRACOVNÍ NEBO ŠKOLNÍ ÚČET",
"require_payment": "Vyžadovat platbu", "require_payment": "Vyžadovat platbu",
"you_need_to_add_a_name": "Musíte přidat název",
"commission_per_transaction": "provize za transakci", "commission_per_transaction": "provize za transakci",
"event_type_updated_successfully_description": "Typ události byl úspěšně aktualizován.", "event_type_updated_successfully_description": "Typ události byl úspěšně aktualizován.",
"hide_event_type": "Skrýt typ události", "hide_event_type": "Skrýt typ události",
@@ -805,18 +865,25 @@
"installed_apps": "Nainstalované aplikace", "installed_apps": "Nainstalované aplikace",
"free_to_use_apps": "Zdarma", "free_to_use_apps": "Zdarma",
"no_category_apps": "Žádné aplikace v kategorii {{category}}", "no_category_apps": "Žádné aplikace v kategorii {{category}}",
"all_apps": "Všechny aplikace",
"no_category_apps_description_calendar": "Přidejte aplikaci kalendáře, ať máte přehled v zájmu prevence dvojích rezervací", "no_category_apps_description_calendar": "Přidejte aplikaci kalendáře, ať máte přehled v zájmu prevence dvojích rezervací",
"no_category_apps_description_conferencing": "Zkuste přidat aplikaci pro videokonference s klienty.",
"no_category_apps_description_payment": "Přidejte platební aplikaci, která usnadní provádění transakcí mezi vámi a vašimi klienty", "no_category_apps_description_payment": "Přidejte platební aplikaci, která usnadní provádění transakcí mezi vámi a vašimi klienty",
"no_category_apps_description_analytics": "Přidejte analytickou aplikaci pro vaše rezervační stránky", "no_category_apps_description_analytics": "Přidejte analytickou aplikaci pro vaše rezervační stránky",
"no_category_apps_description_automation": "Přidejte aplikaci pro automatizaci", "no_category_apps_description_automation": "Přidejte aplikaci pro automatizaci",
"no_category_apps_description_other": "Přidejte jakýkoli jiný typ aplikace pro nejrůznější činnosti", "no_category_apps_description_other": "Přidejte jakýkoli jiný typ aplikace pro nejrůznější činnosti",
"no_category_apps_description_web3": "Přidejte aplikaci web3 pro vaše rezervační stránky", "no_category_apps_description_web3": "Přidejte aplikaci web3 pro vaše rezervační stránky",
"no_category_apps_description_messaging": "Přidejte aplikaci pro zasílání zpráv a nastavte vlastní oznámení a připomenutí",
"no_category_apps_description_crm": "Přidejte aplikaci CRM, ať jste v obraze, s kým jste se setkali",
"installed_app_calendar_description": "Nastavte si kalendáře, ať můžete kontrolovat konflikty a zabránit tak dvojím rezervacím.", "installed_app_calendar_description": "Nastavte si kalendáře, ať můžete kontrolovat konflikty a zabránit tak dvojím rezervacím.",
"installed_app_payment_description": "Nakonfigurujte služby zpracování plateb, které se mají používat při strhávání plateb od klientů.", "installed_app_payment_description": "Nakonfigurujte služby zpracování plateb, které se mají používat při strhávání plateb od klientů.",
"installed_app_analytics_description": "Nakonfigurujte aplikace, které chcete použít pro své rezervační stránky", "installed_app_analytics_description": "Nakonfigurujte aplikace, které chcete použít pro své rezervační stránky",
"installed_app_other_description": "Všechny vaše nainstalované aplikace z ostatních kategorií.", "installed_app_other_description": "Všechny vaše nainstalované aplikace z ostatních kategorií.",
"installed_app_conferencing_description": "Nakonfigurujte konferenční aplikace, které chcete používat",
"installed_app_automation_description": "Konfigurovat aplikace pro automatizaci", "installed_app_automation_description": "Konfigurovat aplikace pro automatizaci",
"installed_app_web3_description": "Nakonfigurujte aplikace web3, které se mají použít pro vaše rezervační stránky", "installed_app_web3_description": "Nakonfigurujte aplikace web3, které se mají použít pro vaše rezervační stránky",
"installed_app_messaging_description": "Nakonfigurujte aplikace pro zasílání zpráv a nastavte vlastní oznámení a připomenutí",
"installed_app_crm_description": "Nakonfigurujte aplikace CRM, které se mají používat ke sledování toho, s kým jste se setkali",
"analytics": "Analytické nástroje", "analytics": "Analytické nástroje",
"empty_installed_apps_headline": "Nenainstalovány žádné aplikace", "empty_installed_apps_headline": "Nenainstalovány žádné aplikace",
"empty_installed_apps_description": "Aplikace vám umožní zlepšit pracovní postupy a výrazně zkvalitnit plánování.", "empty_installed_apps_description": "Aplikace vám umožní zlepšit pracovní postupy a výrazně zkvalitnit plánování.",
@@ -842,6 +909,7 @@
"create_events_on": "Vytvořit události v:", "create_events_on": "Vytvořit události v:",
"enterprise_license": "Jedná se o firemní funkci", "enterprise_license": "Jedná se o firemní funkci",
"enterprise_license_description": "Pokud chcete povolit tuto funkci, získejte klíč pro nasazení v konzoli {{consoleUrl}} a přidejte ho do souboru .env jako CALCOM_LICENSE_KEY. Pokud váš tým již licenci má, kontaktujte prosím {{supportMail}} a požádejte o pomoc.", "enterprise_license_description": "Pokud chcete povolit tuto funkci, získejte klíč pro nasazení v konzoli {{consoleUrl}} a přidejte ho do souboru .env jako CALCOM_LICENSE_KEY. Pokud váš tým již licenci má, kontaktujte prosím {{supportMail}} a požádejte o pomoc.",
"enterprise_license_development": "Tuto funkci můžete vyzkoušet v režimu vývoje. Produkční použití vyžaduje od správce zadání licenčního klíče v <2>/auth/setup</2>.",
"missing_license": "Chybějící licence", "missing_license": "Chybějící licence",
"signup_requires": "Je vyžadována komerční licence", "signup_requires": "Je vyžadována komerční licence",
"signup_requires_description": "{{companyName}} v současné době nenabízí bezplatnou open source verzi stránky registrace. Chcete-li získat plný přístup ke komponentám registrace, musíte získat komerční licenci. Pro osobní použití doporučujeme Prisma Data Platform nebo jakékoli jiné Postgres rozhraní pro vytváření účtů.", "signup_requires_description": "{{companyName}} v současné době nenabízí bezplatnou open source verzi stránky registrace. Chcete-li získat plný přístup ke komponentám registrace, musíte získat komerční licenci. Pro osobní použití doporučujeme Prisma Data Platform nebo jakékoli jiné Postgres rozhraní pro vytváření účtů.",
@@ -911,6 +979,7 @@
"confirm_delete_api_key": "Odvolat tento klíč API", "confirm_delete_api_key": "Odvolat tento klíč API",
"revoke_api_key": "Odvolat klíč API", "revoke_api_key": "Odvolat klíč API",
"api_key_copied": "Klíč API zkopírován!", "api_key_copied": "Klíč API zkopírován!",
"api_key_expires_on": "Platnost klíče API vyprší dne",
"delete_api_key_confirm_title": "Trvale odebrat tento klíč API z vašeho účtu?", "delete_api_key_confirm_title": "Trvale odebrat tento klíč API z vašeho účtu?",
"copy": "Kopírovat", "copy": "Kopírovat",
"expire_date": "Datum uplynutí platnosti", "expire_date": "Datum uplynutí platnosti",
@@ -933,6 +1002,9 @@
"user_impersonation_heading": "Přizpůsobení uživatele", "user_impersonation_heading": "Přizpůsobení uživatele",
"user_impersonation_description": "Náš tým podpory se bude moci dočasně přihlásit místo vás, aby nám pomohl rychle vyřešit jakékoli problémy, které nám nahlásíte.", "user_impersonation_description": "Náš tým podpory se bude moci dočasně přihlásit místo vás, aby nám pomohl rychle vyřešit jakékoli problémy, které nám nahlásíte.",
"team_impersonation_description": "Umožňuje vašim vlastníkům/správcům týmu dočasně se přihlásit jako vy.", "team_impersonation_description": "Umožňuje vašim vlastníkům/správcům týmu dočasně se přihlásit jako vy.",
"make_team_private": "Soukromý tým",
"make_team_private_description": "Po zapnutí této funkce nebudou členové vašeho týmu vidět ostatní členy týmu.",
"you_cannot_see_team_members": "V soukromém týmu nelze vidět všechny členy týmu.",
"allow_booker_to_select_duration": "Umožnit rezervující osobě vybrat dobu trvání", "allow_booker_to_select_duration": "Umožnit rezervující osobě vybrat dobu trvání",
"impersonate_user_tip": "Všechna použití této funkce jsou kontrolována.", "impersonate_user_tip": "Všechna použití této funkce jsou kontrolována.",
"impersonating_user_warning": "Zosobnění uživatelského jména „{{user}}“.", "impersonating_user_warning": "Zosobnění uživatelského jména „{{user}}“.",
@@ -1000,16 +1072,21 @@
"event_location": "Místo události", "event_location": "Místo události",
"reschedule_optional": "Důvod pro změnu plánu (volitelné)", "reschedule_optional": "Důvod pro změnu plánu (volitelné)",
"reschedule_placeholder": "Dejte ostatním vědět, proč potřebujete změnit plán", "reschedule_placeholder": "Dejte ostatním vědět, proč potřebujete změnit plán",
"event_cancelled": "Tato událost je zrušena",
"emailed_information_about_cancelled_event": "Poslali jsme vám a ostatním účastníkům informační e-mail.", "emailed_information_about_cancelled_event": "Poslali jsme vám a ostatním účastníkům informační e-mail.",
"this_input_will_shown_booking_this_event": "Toto pole se zobrazí při rezervaci této události", "this_input_will_shown_booking_this_event": "Toto pole se zobrazí při rezervaci této události",
"meeting_url_in_conformation_email": "Adresa URL schůzky je v potvrzovacím e-mailu", "meeting_url_in_conformation_email": "Adresa URL schůzky je v potvrzovacím e-mailu",
"url_start_with_https": "Adresa URL musí začínat http:// nebo https://", "url_start_with_https": "Adresa URL musí začínat http:// nebo https://",
"number_provided": "Bude uvedeno telefonní číslo", "number_provided": "Bude uvedeno telefonní číslo",
"before_event_trigger": "před zahájením události", "before_event_trigger": "před zahájením události",
"event_cancelled_trigger": "při zrušení události",
"new_event_trigger": "při rezervaci nové události", "new_event_trigger": "při rezervaci nové události",
"email_host_action": "odeslání e-mailu hostiteli", "email_host_action": "odeslání e-mailu hostiteli",
"email_attendee_action": "odeslat e-mail účastníkům", "email_attendee_action": "odeslat e-mail účastníkům",
"sms_attendee_action": "Odeslat SMS účastníkovi",
"sms_number_action": "odeslání SMS na konkrétní číslo", "sms_number_action": "odeslání SMS na konkrétní číslo",
"whatsapp_number_action": "odeslat Whatsapp na konkrétní číslo",
"whatsapp_attendee_action": "odeslat Whatsapp účastníkovi",
"workflows": "Pracovní postupy", "workflows": "Pracovní postupy",
"new_workflow_btn": "Nový pracovní postup", "new_workflow_btn": "Nový pracovní postup",
"add_new_workflow": "Přidat nový pracovní postup", "add_new_workflow": "Přidat nový pracovní postup",
@@ -1073,6 +1150,8 @@
"choose_template": "Vyberte si šablonu", "choose_template": "Vyberte si šablonu",
"custom": "Vlastní", "custom": "Vlastní",
"reminder": "Upomínka", "reminder": "Upomínka",
"rescheduled": "Změna termínu",
"completed": "Dokončeno",
"reminder_email": "Upomínka: událost {{eventType}} s uživatelem {{name}} dne {{date}}", "reminder_email": "Upomínka: událost {{eventType}} s uživatelem {{name}} dne {{date}}",
"not_triggering_existing_bookings": "Nespustí se u již existujících rezervací, protože uživatel bude při rezervaci události požádán o zadání telefonního čísla.", "not_triggering_existing_bookings": "Nespustí se u již existujících rezervací, protože uživatel bude při rezervaci události požádán o zadání telefonního čísla.",
"minute_one": "{{count}} min", "minute_one": "{{count}} min",
@@ -1170,6 +1249,7 @@
"start_of_week": "Začátek týdne", "start_of_week": "Začátek týdne",
"recordings_title": "Nahrávky", "recordings_title": "Nahrávky",
"recording": "Nahrávka", "recording": "Nahrávka",
"happy_scheduling": "Hezké plánování",
"select_calendars": "Vyberte kalendáře, u kterých chcete kontrolovat konflikty v zájmu prevence dvojích rezervací.", "select_calendars": "Vyberte kalendáře, u kterých chcete kontrolovat konflikty v zájmu prevence dvojích rezervací.",
"check_for_conflicts": "Zkontrolovat konflikty", "check_for_conflicts": "Zkontrolovat konflikty",
"view_recordings": "Zobrazit nahrávky", "view_recordings": "Zobrazit nahrávky",
@@ -1211,6 +1291,7 @@
"conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky", "conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky",
"add_conferencing_app": "Přidat videokonferenční aplikaci", "add_conferencing_app": "Přidat videokonferenční aplikaci",
"password_description": "Správa nastavení hesel k vašemu účtu", "password_description": "Správa nastavení hesel k vašemu účtu",
"set_up_two_factor_authentication": "Nastavení dvoufaktorového ověřování",
"we_just_need_basic_info": "K nastavení vašeho profilu potřebujeme jen několik základních informací.", "we_just_need_basic_info": "K nastavení vašeho profilu potřebujeme jen několik základních informací.",
"skip": "Přeskočit", "skip": "Přeskočit",
"do_this_later": "Provést později", "do_this_later": "Provést později",
@@ -1224,6 +1305,8 @@
"connect_analytics_apps": "Připojit analytické aplikace", "connect_analytics_apps": "Připojit analytické aplikace",
"connect_other_apps": "Propojit další aplikace", "connect_other_apps": "Propojit další aplikace",
"connect_web3_apps": "Připojení aplikací web3", "connect_web3_apps": "Připojení aplikací web3",
"connect_messaging_apps": "Připojení aplikací pro zasílání zpráv",
"connect_crm_apps": "Připojení aplikací CRM",
"current_step_of_total": "Krok {{currentStep}} / {{maxSteps}}", "current_step_of_total": "Krok {{currentStep}} / {{maxSteps}}",
"add_variable": "Přidat proměnnou", "add_variable": "Přidat proměnnou",
"custom_phone_number": "Vlastní telefonní číslo", "custom_phone_number": "Vlastní telefonní číslo",
@@ -1236,12 +1319,14 @@
"location_info": "Místo události", "location_info": "Místo události",
"additional_notes_info": "Další poznámky k rezervaci", "additional_notes_info": "Další poznámky k rezervaci",
"attendee_name_info": "Jméno osoby provádějící rezervaci", "attendee_name_info": "Jméno osoby provádějící rezervaci",
"organizer_name_info": "Jméno organizátora",
"to": "Komu", "to": "Komu",
"workflow_turned_on_successfully": "Pracovní postup {{workflowName}} byl {{offOn}}", "workflow_turned_on_successfully": "Pracovní postup {{workflowName}} byl {{offOn}}",
"download_responses": "Stáhnout odpovědi", "download_responses": "Stáhnout odpovědi",
"download_responses_description": "Stáhněte si všechny odpovědi do formuláře ve formátu CSV.", "download_responses_description": "Stáhněte si všechny odpovědi do formuláře ve formátu CSV.",
"download": "Stáhnout", "download": "Stáhnout",
"download_recording": "Stáhnout nahrávku", "download_recording": "Stáhnout nahrávku",
"recording_from_your_recent_call": "Nahrávka z vašeho nedávného hovoru v {{appName}} je připravena ke stažení.",
"create_your_first_form": "Vytvořte svůj první formulář", "create_your_first_form": "Vytvořte svůj první formulář",
"create_your_first_form_description": "Pomocí adresných formulářů můžete klást kvalifikační otázky a adresovat je správné osobě nebo typu události.", "create_your_first_form_description": "Pomocí adresných formulářů můžete klást kvalifikační otázky a adresovat je správné osobě nebo typu události.",
"create_your_first_webhook": "Vytvořte svůj první webhook", "create_your_first_webhook": "Vytvořte svůj první webhook",
@@ -1250,7 +1335,9 @@
"event_one": "událost", "event_one": "událost",
"event_other": "událostí", "event_other": "událostí",
"profile_team_description": "Správa nastavení profilu vašeho týmu", "profile_team_description": "Správa nastavení profilu vašeho týmu",
"profile_org_description": "Správa nastavení profilu organizace",
"members_team_description": "Uživatelé, kteří jsou ve skupině", "members_team_description": "Uživatelé, kteří jsou ve skupině",
"organization_description": "Správa správců a členů vaší organizace",
"team_url": "Adresa URL týmu", "team_url": "Adresa URL týmu",
"team_members": "Členové týmu", "team_members": "Členové týmu",
"more": "Více", "more": "Více",
@@ -1291,6 +1378,7 @@
"routing_forms_send_email_owner": "Odeslat e-mail vlastníkovi", "routing_forms_send_email_owner": "Odeslat e-mail vlastníkovi",
"routing_forms_send_email_owner_description": "Po odeslání formuláře bude vlastníkovi odeslán e-mail", "routing_forms_send_email_owner_description": "Po odeslání formuláře bude vlastníkovi odeslán e-mail",
"add_new_form": "Přidat nový formulář", "add_new_form": "Přidat nový formulář",
"add_new_team_form": "Přidání nového formuláře do vašeho týmu",
"create_your_first_route": "Vytvořte svoje první směrování", "create_your_first_route": "Vytvořte svoje první směrování",
"route_to_the_right_person": "Nasměrovat té správné osobě na základě odpovědí ve vašem formuláři", "route_to_the_right_person": "Nasměrovat té správné osobě na základě odpovědí ve vašem formuláři",
"form_description": "Vytvořte vlastní formulář, který adresujete rezervující osobě", "form_description": "Vytvořte vlastní formulář, který adresujete rezervující osobě",
@@ -1376,6 +1464,7 @@
"new_event_type_availability": "Dostupnost pro {{eventTypeTitle}}", "new_event_type_availability": "Dostupnost pro {{eventTypeTitle}}",
"error_editing_availability": "Chyba při úpravě dostupnosti", "error_editing_availability": "Chyba při úpravě dostupnosti",
"dont_have_permission": "Nemáte oprávnění k přístupu k tomuto dokumentu.", "dont_have_permission": "Nemáte oprávnění k přístupu k tomuto dokumentu.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Vložte sem SAML metadata vašeho Identity Providera", "saml_configuration_placeholder": "Vložte sem SAML metadata vašeho Identity Providera",
"saml_email_required": "Zadejte prosím e-mail, abychom mohli určit vašeho SAML Identity Providera", "saml_email_required": "Zadejte prosím e-mail, abychom mohli určit vašeho SAML Identity Providera",
"saml_sp_title": "Podrobnosti poskytovatele služby", "saml_sp_title": "Podrobnosti poskytovatele služby",
@@ -1394,15 +1483,19 @@
"yearly": "Ročně", "yearly": "Ročně",
"checkout": "Platba", "checkout": "Platba",
"your_team_disbanded_successfully": "Váš tým byl úspěšně rozpuštěn", "your_team_disbanded_successfully": "Váš tým byl úspěšně rozpuštěn",
"your_org_disbanded_successfully": "Vaše organizace byla rozpuštěna",
"error_creating_team": "Chyba při vytváření týmu", "error_creating_team": "Chyba při vytváření týmu",
"you": "Vy", "you": "Vy",
"resend_email": "Znovu odeslat e-mail",
"member_already_invited": "Člen byl už pozván", "member_already_invited": "Člen byl už pozván",
"enter_email_or_username": "Zadejte e-mail nebo uživatelské jméno", "enter_email_or_username": "Zadejte e-mail nebo uživatelské jméno",
"team_name_taken": "Toto jméno je už obsazeno", "team_name_taken": "Toto jméno je už obsazeno",
"must_enter_team_name": "Musíte zadat název týmu", "must_enter_team_name": "Musíte zadat název týmu",
"team_url_required": "Musíte zadat adresu URL týmu", "team_url_required": "Musíte zadat adresu URL týmu",
"url_taken": "Tato adresa URL je už obsazená", "url_taken": "Tato adresa URL je už obsazená",
"problem_registering_domain": "Při registraci subdomény došlo k problému, zkuste to prosím znovu nebo kontaktujte správce",
"team_publish": "Zveřejnit tým", "team_publish": "Zveřejnit tým",
"number_text_notifications": "Telefonní číslo (SMS oznámení)",
"attendee_email_variable": "E-mail účastníka", "attendee_email_variable": "E-mail účastníka",
"attendee_email_info": "E-mail osoby provádějící rezervaci", "attendee_email_info": "E-mail osoby provádějící rezervaci",
"kbar_search_placeholder": "Zadejte příkaz nebo vyhledejte...", "kbar_search_placeholder": "Zadejte příkaz nebo vyhledejte...",
@@ -1425,6 +1518,8 @@
"find_the_best_person": "Najděte nejlepší dostupnou osobu a procházejte tým.", "find_the_best_person": "Najděte nejlepší dostupnou osobu a procházejte tým.",
"fixed_round_robin": "Pevný „round robin“", "fixed_round_robin": "Pevný „round robin“",
"add_one_fixed_attendee": "Přidejte jednoho pevně stanoveného účastníka a „round robin“ přes daný počet účastníků.", "add_one_fixed_attendee": "Přidejte jednoho pevně stanoveného účastníka a „round robin“ přes daný počet účastníků.",
"calcom_is_better_with_team": "{{appName}} je lepší pro týmy",
"the_calcom_team": "Tým společnosti {{companyName}}",
"add_your_team_members": "Přidejte členy týmu k typům událostí. Použijte kolektivní plánování, abyste zahrnuli všechny, případně vyhledejte tu nejvhodnější osobu s plánováním „round robin“.", "add_your_team_members": "Přidejte členy týmu k typům událostí. Použijte kolektivní plánování, abyste zahrnuli všechny, případně vyhledejte tu nejvhodnější osobu s plánováním „round robin“.",
"booking_limit_reached": "Byl dosažen limit rezervací pro tento typ události", "booking_limit_reached": "Byl dosažen limit rezervací pro tento typ události",
"duration_limit_reached": "Byl dosažen limit doby trvání pro tento typ události", "duration_limit_reached": "Byl dosažen limit doby trvání pro tento typ události",
@@ -1443,6 +1538,7 @@
"navigate_installed_apps": "Přejděte na nainstalované aplikace", "navigate_installed_apps": "Přejděte na nainstalované aplikace",
"disabled_calendar": "Pokud máte nainstalovaný jiný kalendář, budou do něj přidány nové rezervace. Pokud ne, připojte nový kalendář, abyste nepřišli o žádné nové rezervace.", "disabled_calendar": "Pokud máte nainstalovaný jiný kalendář, budou do něj přidány nové rezervace. Pokud ne, připojte nový kalendář, abyste nepřišli o žádné nové rezervace.",
"enable_apps": "Povolit aplikace", "enable_apps": "Povolit aplikace",
"enable_apps_description": "Zapněte aplikace, které mohou uživatelé integrovat s aplikací {{appName}}",
"purchase_license": "Kupte si licenci", "purchase_license": "Kupte si licenci",
"already_have_key": "Klíč již mám:", "already_have_key": "Klíč již mám:",
"already_have_key_suggestion": "Zkopírujte sem svou stávající proměnnou prostředí CALCOM_LICENSE_KEY.", "already_have_key_suggestion": "Zkopírujte sem svou stávající proměnnou prostředí CALCOM_LICENSE_KEY.",
@@ -1456,6 +1552,9 @@
"no_available_apps": "Nejsou k dispozici žádné aplikace", "no_available_apps": "Nejsou k dispozici žádné aplikace",
"no_available_apps_description": "Zkontrolujte, zda máte ve svém nasazení v části „packages/app-store“ k dispozici aplikace", "no_available_apps_description": "Zkontrolujte, zda máte ve svém nasazení v části „packages/app-store“ k dispozici aplikace",
"no_apps": "V této instanci Cal nejsou povoleny žádné aplikace", "no_apps": "V této instanci Cal nejsou povoleny žádné aplikace",
"no_apps_configured": "Zatím nebyla nakonfigurována žádná aplikace",
"enable_in_settings": "Aplikace můžete zapnout v nastavení",
"please_contact_admin": "Kontaktujte prosím svého správce",
"apps_settings": "Nastavení aplikací", "apps_settings": "Nastavení aplikací",
"fill_this_field": "Vyplňte prosím toto pole", "fill_this_field": "Vyplňte prosím toto pole",
"options": "Možnosti", "options": "Možnosti",
@@ -1559,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "Opravdu chcete odstranit konfiguraci {{connectionType}}? Členové vašeho týmu, kteří používají přihlášení {{connectionType}}, ztratí přístup k webu Cal.com.", "delete_sso_configuration_confirmation_description": "Opravdu chcete odstranit konfiguraci {{connectionType}}? Členové vašeho týmu, kteří používají přihlášení {{connectionType}}, ztratí přístup k webu Cal.com.",
"organizer_timezone": "Časové pásmo organizátora", "organizer_timezone": "Časové pásmo organizátora",
"email_user_cta": "Zobrazit pozvánku", "email_user_cta": "Zobrazit pozvánku",
"email_no_user_invite_heading": "Byli jste pozváni, abyste se připojili k subjektu {{{entity}} v aplikaci {{appName}}",
"email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.", "email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.",
"email_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k týmu {{teamName}} subjektu ({{entity}}) v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu subjektu ({{entity}}) umožňuje plánovat schůzky bez e-mailového pingpongu.",
"email_no_user_invite_steps_intro": "Provedeme vás několika krátkými kroky a za malou chvíli si budete se svým subjektem ({{entity}}) užívat plánování bez stresu.",
"email_no_user_step_one": "Vyberte si uživatelské jméno", "email_no_user_step_one": "Vyberte si uživatelské jméno",
"email_no_user_step_two": "Připojte svůj účet kalendáře", "email_no_user_step_two": "Připojte svůj účet kalendáře",
"email_no_user_step_three": "Nastavte si dostupnost", "email_no_user_step_three": "Nastavte si dostupnost",
@@ -1570,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "Žádné pracovní postupy", "no_workflows": "Žádné pracovní postupy",
"change_filter": "Změňte filtr, abyste viděli osobní i týmové pracovní postupy.", "change_filter": "Změňte filtr, abyste viděli osobní i týmové pracovní postupy.",
"change_filter_common": "Změňte filtr a prohlédněte si výsledky.",
"no_results_for_filter": "Tento filtr neposkytl žádné výsledky",
"recommended_next_steps": "Doporučené další kroky", "recommended_next_steps": "Doporučené další kroky",
"create_a_managed_event": "Vytvořte typ spravované události", "create_a_managed_event": "Vytvořte typ spravované události",
"meetings_are_better_with_the_right": "Schůzky jsou lepší, když jsou na nich přítomni ti správní členové týmu. Pozvěte je.", "meetings_are_better_with_the_right": "Schůzky jsou lepší, když jsou na nich přítomni ti správní členové týmu. Pozvěte je.",
@@ -1580,7 +1684,9 @@
"no_longer_attending": "Této události se již neúčastníte", "no_longer_attending": "Této události se již neúčastníte",
"attendee_no_longer_attending_subject": "Účastník se již neúčastní události {{title}} v den {{date}}", "attendee_no_longer_attending_subject": "Účastník se již neúčastní události {{title}} v den {{date}}",
"attendee_no_longer_attending": "Účastník se již neúčastní vaší události", "attendee_no_longer_attending": "Účastník se již neúčastní vaší události",
"attendee_no_longer_attending_subtitle": "Uživatel {{name}} zrušil svou účast. V tomto časovém intervalu se tedy uvolnilo místo",
"create_event_on": "Vytvořit událost v:", "create_event_on": "Vytvořit událost v:",
"create_routing_form_on": "Vytvoření směrovacího formuláře v",
"default_app_link_title": "Nastavte výchozí odkaz na aplikaci", "default_app_link_title": "Nastavte výchozí odkaz na aplikaci",
"default_app_link_description": "Nastavení výchozího odkazu na aplikaci umožní, aby všechny nově vytvořené typy událostí používaly vámi nastavený odkaz na aplikaci.", "default_app_link_description": "Nastavení výchozího odkazu na aplikaci umožní, aby všechny nově vytvořené typy událostí používaly vámi nastavený odkaz na aplikaci.",
"organizer_default_conferencing_app": "Výchozí aplikace organizátora", "organizer_default_conferencing_app": "Výchozí aplikace organizátora",
@@ -1590,6 +1696,7 @@
"booking_questions_title": "Otázky k rezervaci", "booking_questions_title": "Otázky k rezervaci",
"booking_questions_description": "Přizpůsobte otázky položené na stránce rezervace", "booking_questions_description": "Přizpůsobte otázky položené na stránce rezervace",
"add_a_booking_question": "Přidat otázku", "add_a_booking_question": "Přidat otázku",
"identifier": "Identifikátor",
"duplicate_email": "Duplicitní e-mail", "duplicate_email": "Duplicitní e-mail",
"booking_with_payment_cancelled": "Platba za tuto událost již není možná", "booking_with_payment_cancelled": "Platba za tuto událost již není možná",
"booking_with_payment_cancelled_already_paid": "Vrácení peněz za tuto rezervační platbu je na cestě.", "booking_with_payment_cancelled_already_paid": "Vrácení peněz za tuto rezervační platbu je na cestě.",
@@ -1600,6 +1707,7 @@
"show_on_booking_page": "Zobrazit na stránce rezervace", "show_on_booking_page": "Zobrazit na stránce rezervace",
"get_started_zapier_templates": "Začněte používat šablony Zapier", "get_started_zapier_templates": "Začněte používat šablony Zapier",
"team_is_unpublished": "Tým {{team}} není zveřejněn", "team_is_unpublished": "Tým {{team}} není zveřejněn",
"team_is_unpublished_description": "Tento odkaz subjektu ({{entity}}) není v současné době k dispozici. Kontaktujte prosím vlastníka subjektu ({{entity}}) nebo ho požádejte o jeho zveřejnění.",
"team_member": "Člen týmu", "team_member": "Člen týmu",
"a_routing_form": "Směrovací formulář", "a_routing_form": "Směrovací formulář",
"form_description_placeholder": "Popis formuláře", "form_description_placeholder": "Popis formuláře",
@@ -1629,13 +1737,16 @@
"spot_popular_event_types": "Identifikujte oblíbené typy událostí", "spot_popular_event_types": "Identifikujte oblíbené typy událostí",
"spot_popular_event_types_description": "Zjistěte, které typy vašich událostí získávají nejvíce kliknutí a rezervací", "spot_popular_event_types_description": "Zjistěte, které typy vašich událostí získávají nejvíce kliknutí a rezervací",
"no_responses_yet": "Zatím žádné odpovědi", "no_responses_yet": "Zatím žádné odpovědi",
"no_routes_defined": "Není definováno žádné směrování",
"this_will_be_the_placeholder": "Toto bude zástupný znak", "this_will_be_the_placeholder": "Toto bude zástupný znak",
"error_booking_event": "Při rezervaci události došlo k chybě, obnovte prosím stránku a zkuste to znovu.",
"timeslot_missing_title": "Nebyl vybrán žádný časový slot", "timeslot_missing_title": "Nebyl vybrán žádný časový slot",
"timeslot_missing_description": "Vyberte časový slot, aby mohla být událost zaregistrována.", "timeslot_missing_description": "Vyberte časový slot, aby mohla být událost zaregistrována.",
"timeslot_missing_cta": "Vybrat časový slot", "timeslot_missing_cta": "Vybrat časový slot",
"switch_monthly": "Přepnout na měsíční zobrazení", "switch_monthly": "Přepnout na měsíční zobrazení",
"switch_weekly": "Přepnout na týdenní zobrazení", "switch_weekly": "Přepnout na týdenní zobrazení",
"switch_multiday": "Přepnout na denní zobrazení", "switch_multiday": "Přepnout na denní zobrazení",
"switch_columnview": "Přepněte na sloupcové zobrazení",
"num_locations": "Počet míst konání: {{num}}", "num_locations": "Počet míst konání: {{num}}",
"select_on_next_step": "Vyberte v dalším kroku", "select_on_next_step": "Vyberte v dalším kroku",
"this_meeting_has_not_started_yet": "Tato schůzka ještě nezačala", "this_meeting_has_not_started_yet": "Tato schůzka ještě nezačala",
@@ -1674,6 +1785,7 @@
"managed_event_dialog_title_one": "Adresa URL /{{slug}} již existuje pro {{count}} člena. Chcete ji nahradit?", "managed_event_dialog_title_one": "Adresa URL /{{slug}} již existuje pro {{count}} člena. Chcete ji nahradit?",
"managed_event_dialog_title_other": "Adresa URL /{{slug}} již existuje pro ({{count}}) členy. Chcete ji nahradit?", "managed_event_dialog_title_other": "Adresa URL /{{slug}} již existuje pro ({{count}}) členy. Chcete ji nahradit?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> již používá adresu URL <strong>/{{slug}}</strong>.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> již používá adresu URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> již používají adresu URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_clarification": "Pokud se rozhodnete ji nahradit, pošleme jim upozornění. Pokud ji nechcete přepsat, vraťte se a odstraňte ji.", "managed_event_dialog_clarification": "Pokud se rozhodnete ji nahradit, pošleme jim upozornění. Pokud ji nechcete přepsat, vraťte se a odstraňte ji.",
"review_event_type": "Revidovat typ události", "review_event_type": "Revidovat typ události",
"looking_for_more_analytics": "Hledáte další analytické informace?", "looking_for_more_analytics": "Hledáte další analytické informace?",
@@ -1689,12 +1801,14 @@
"least_booked_members": "Nejméně rezervovaných členů", "least_booked_members": "Nejméně rezervovaných členů",
"events_created": "Události vytvořeny", "events_created": "Události vytvořeny",
"events_completed": "Události dokončeny", "events_completed": "Události dokončeny",
"events_cancelled": "Události zrušeny",
"events_rescheduled": "Události přesunuty", "events_rescheduled": "Události přesunuty",
"from_last_period": "z posledního období", "from_last_period": "z posledního období",
"from_to_date_period": "Od: {{startDate}} do: {{endDate}}", "from_to_date_period": "Od: {{startDate}} do: {{endDate}}",
"redirect_url_warning": "Přidáním přesměrování se stránka úspěchu vypne. Nezapomeňte na vlastní stránce úspěchu uvést „Rezervace potvrzena“.", "redirect_url_warning": "Přidáním přesměrování se stránka úspěchu vypne. Nezapomeňte na vlastní stránce úspěchu uvést „Rezervace potvrzena“.",
"event_trends": "Trendy událostí", "event_trends": "Trendy událostí",
"clear_filters": "Vymazat filtry", "clear_filters": "Vymazat filtry",
"clear": "Vymazat",
"hold": "Blokace", "hold": "Blokace",
"on_booking_option": "Vybrat platbu při rezervaci", "on_booking_option": "Vybrat platbu při rezervaci",
"hold_option": "Účtovat poplatek za nedostavení se", "hold_option": "Účtovat poplatek za nedostavení se",
@@ -1721,6 +1835,18 @@
"complete_your_booking": "Dokončete svou rezervaci", "complete_your_booking": "Dokončete svou rezervaci",
"complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}", "complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}",
"confirm_your_details": "Potvrďte své údaje", "confirm_your_details": "Potvrďte své údaje",
"copy_invite_link": "Zkopírovat odkaz pozvánky",
"edit_invite_link": "Upravit nastavení odkazu",
"invite_link_copied": "Odkaz pozvánky zkopírován",
"invite_link_deleted": "Odkaz pozvánky odstraněn",
"invite_link_updated": "Nastavení odkazu pozvánky uloženo",
"link_expires_after": "Platnost odkazů vyprší za...",
"one_day": "1 den",
"seven_days": "7 dní",
"thirty_days": "30 dní",
"three_months": "3 měsíce",
"one_year": "1 rok",
"team_invite_received": "Byli jste pozváni do týmu {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Chystáte se účtovat účastníkovi {{amount, currency}}. Opravdu chcete pokračovat?", "charge_card_dialog_body": "Chystáte se účtovat účastníkovi {{amount, currency}}. Opravdu chcete pokračovat?",
"charge_attendee": "Naúčtovat účastníkovi {{amount, currency}}", "charge_attendee": "Naúčtovat účastníkovi {{amount, currency}}",
@@ -1729,6 +1855,7 @@
"email_invite_team_bulk": "Počet pozvaných uživatelů: {{userCount}}", "email_invite_team_bulk": "Počet pozvaných uživatelů: {{userCount}}",
"error_collecting_card": "Chyba při výběru karty", "error_collecting_card": "Chyba při výběru karty",
"image_size_limit_exceed": "Velikost nahraného obrázku by neměla překročit limit 5 MB", "image_size_limit_exceed": "Velikost nahraného obrázku by neměla překročit limit 5 MB",
"unauthorized_workflow_error_message": "{{errorCode}}: Nejste oprávněni zapnout nebo vypnout tento pracovní postup.",
"inline_embed": "Vložit na řádek", "inline_embed": "Vložit na řádek",
"load_inline_content": "Načte váš typ události přímo do řádků s ostatním obsahem webu.", "load_inline_content": "Načte váš typ události přímo do řádků s ostatním obsahem webu.",
"floating_pop_up_button": "Plovoucí překryvné tlačítko", "floating_pop_up_button": "Plovoucí překryvné tlačítko",
@@ -1748,6 +1875,69 @@
"connect_google_workspace": "Propojit s Google Workspace", "connect_google_workspace": "Propojit s Google Workspace",
"google_workspace_admin_tooltip": "Používání této funkce vyžaduje, abyste byli administrátory pracovního prostoru", "google_workspace_admin_tooltip": "Používání této funkce vyžaduje, abyste byli administrátory pracovního prostoru",
"first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události", "first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události",
"install_app_on": "Nainstalovat aplikaci v",
"create_for": "Vytvořit pro", "create_for": "Vytvořit pro",
"insights_all_org_filter": "Všechny aplikace" "setup_organization": "Nastavení organizace",
"organization_banner_description": "Vytvořte prostředí, ve kterém budou moct vaše týmy vytvářet sdílené aplikace, pracovní postupy a typy událostí s kolektivním plánováním nebo plánováním typu round-robin.",
"organization_banner_title": "Správa organizace s více týmy",
"set_up_your_organization": "Nastavení organizace",
"organizations_description": "Organizace jsou sdílená prostředí, ve kterých mohou týmy vytvářet sdílené typy událostí, aplikace, pracovní postupy a mnoho dalšího.",
"must_enter_organization_name": "Je nutné zadat název organizace",
"must_enter_organization_admin_email": "Je nutné zadat e-mailovou adresu organizace",
"admin_email": "E-mailová adresa vaší organizace",
"admin_username": "Uživatelské jméno správce",
"organization_name": "Název organizace",
"organization_url": "Adresa URL organizace",
"organization_verify_header": "Ověřte e-mailovou adresu organizace",
"organization_verify_email_body": "Pomocí uvedeného kódu ověřte vaši e-mailovou adresu, abyste mohli pokračovat v nastavení vaší organizace.",
"additional_url_parameters": "Další parametry adresy URL",
"about_your_organization": "Informace o vaší organizaci",
"about_your_organization_description": "Organizace jsou sdílená prostředí, ve kterých můžete vytvořit několik týmů se sdílenými členy, typy událostí, aplikacemi, pracovními postupy a mnoha dalšími věcmi.",
"create_your_teams": "Vytvoření týmů",
"create_your_teams_description": "Přidejte do své organizace členy a pusťte se do společného plánování.",
"invite_organization_admins": "Pozvěte správce své organizace",
"invite_organization_admins_description": "Tito správci budou mít přístup ke všem týmům ve vaší organizaci. Správce a členy týmů můžete přidat později.",
"set_a_password": "Nastavte heslo",
"set_a_password_description": "Tím se vytvoří nový uživatelský účet s e-mailem vaší organizace a tímto heslem.",
"organization_logo": "Logo organizace",
"organization_about_description": "Několik vět o vaší organizaci. Objeví se na veřejné stránce profilu vaší organizace.",
"ill_do_this_later": "Udělám to později",
"verify_your_email": "Ověřte svůj e-mail",
"enter_digit_code": "Zadejte šestimístný kód, který jsme vám zaslali na {{email}}",
"verify_email_organization": "Ověřte svůj e-mail a vytvořte organizaci",
"code_provided_invalid": "Zadaný kód není platný, zkuste to znovu",
"email_already_used": "E-mail se již používá",
"organization_admin_invited_heading": "Byli jste pozváni do organizace {{orgName}}",
"organization_admin_invited_body": "Připojte se k týmu organizace {{orgName}} a začněte se soustředit na samotné schůzky, ne na vytváření schůzek!",
"duplicated_slugs_warning": "Následující týmy nemohly být vytvořeny kvůli duplicitním slugům: {{slugs}}",
"team_names_empty": "Názvy týmů nemohou být prázdné",
"team_names_repeated": "Názvy týmů se nemohou opakovat",
"user_belongs_organization": "Uživatel patří do organizace",
"org_no_teams_yet": "Tato organizace zatím neobsahuje žádné týmy",
"org_no_teams_yet_description": "Pokud jste správce, nezapomeňte vytvořit týmy, které se zde budou zobrazovat.",
"set_up": "Nastavení",
"set_up_your_profile": "Nastavení profilu",
"set_up_your_profile_description": "Dejte lidem vědět, co v rámci organizace {{orgName}} děláte, pokud si otevřou váš veřejný odkaz.",
"my_profile": "Můj profil",
"my_settings": "Moje nastavení",
"crm": "CRM",
"messaging": "Zasílání zpráv",
"sender_id_info": "Jméno nebo číslo zobrazené jako odesílatel SMS (některé země nepovolují alfanumerické ID odesílatele).",
"org_admins_can_create_new_teams": "Nové týmy může vytvářet pouze správce vaší organizace",
"google_new_spam_policy": "Nové zásady společnosti Google týkající se nevyžádané pošty by mohly zabránit tomu, abyste dostávali e-mailová oznámení a oznámení kalendáře o této rezervaci.",
"resolve": "Vyřešit",
"no_organization_slug": "Při vytváření týmů pro tuto organizaci došlo k chybě. Chybějící slug adresy URL.",
"org_name": "Název organizace",
"org_url": "Adresa URL organizace",
"copy_link_org": "Zkopírovat odkaz na organizaci",
"404_the_org": "Organizace",
"404_the_team": "Tým",
"404_claim_entity_org": "Vyžádejte si subdoménu pro svou organizaci",
"404_claim_entity_team": "Vyžádejte si tento tým a začněte kolektivně spravovat rozvrhy",
"insights_all_org_filter": "Všechny aplikace",
"insights_team_filter": "Tým: {{teamName}}",
"insights_user_filter": "Uživatel: {{userName}}",
"insights_subtitle": "Zobrazte si přehled o rezervacích napříč vašimi událostmi",
"custom_plan": "Vlastní plán",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -17,6 +17,7 @@
"verify_email_banner_body": "Bestätigen Sie Ihre E-Mail-Adresse, um die beste Zustellbarkeit von E-Mails und Kalenderdaten zu gewährleisten", "verify_email_banner_body": "Bestätigen Sie Ihre E-Mail-Adresse, um die beste Zustellbarkeit von E-Mails und Kalenderdaten zu gewährleisten",
"verify_email_email_header": "Bestätigen Sie Ihre E-Mail-Adresse", "verify_email_email_header": "Bestätigen Sie Ihre E-Mail-Adresse",
"verify_email_email_button": "E-Mail bestätigen", "verify_email_email_button": "E-Mail bestätigen",
"copy_somewhere_safe": "Speichern Sie diesen API-Schlüssel an einem sicheren Ort. Sie können ihn nicht erneut ansehen.",
"verify_email_email_body": "Bitte bestätigen Sie Ihre E-Mail-Adresse, indem Sie unten auf die Schaltfläche klicken.", "verify_email_email_body": "Bitte bestätigen Sie Ihre E-Mail-Adresse, indem Sie unten auf die Schaltfläche klicken.",
"verify_email_email_link_text": "Hier ist der Link, falls Sie lieber keine Schaltflächen anklicken möchten:", "verify_email_email_link_text": "Hier ist der Link, falls Sie lieber keine Schaltflächen anklicken möchten:",
"email_sent": "E-Mail erfolgreich gesendet", "email_sent": "E-Mail erfolgreich gesendet",
@@ -84,7 +85,7 @@
"booking_submitted_subject": "Buchung eingereicht: {{title}} am {{date}}", "booking_submitted_subject": "Buchung eingereicht: {{title}} am {{date}}",
"download_recording_subject": "Aufnahme herunterladen: {{title}} am {{date}}", "download_recording_subject": "Aufnahme herunterladen: {{title}} am {{date}}",
"download_your_recording": "Ihre Aufnahme herunterladen", "download_your_recording": "Ihre Aufnahme herunterladen",
"your_meeting_has_been_booked": "Dein Termin wurde gebucht", "your_meeting_has_been_booked": "Ihr Termin wurde gebucht",
"event_type_has_been_rescheduled_on_time_date": "Ihr {{title}} wurde auf den {{date}} verschoben.", "event_type_has_been_rescheduled_on_time_date": "Ihr {{title}} wurde auf den {{date}} verschoben.",
"event_has_been_rescheduled": "Ihr Termin wurde verschoben.", "event_has_been_rescheduled": "Ihr Termin wurde verschoben.",
"request_reschedule_subtitle": "{{organizer}} hat die Buchung storniert und Sie gebeten, eine andere Zeit auszuwählen.", "request_reschedule_subtitle": "{{organizer}} hat die Buchung storniert und Sie gebeten, eine andere Zeit auszuwählen.",
@@ -243,6 +244,8 @@
"all": "Alle Apps", "all": "Alle Apps",
"yours": "Ihr Konto", "yours": "Ihr Konto",
"available_apps": "Verfügbare Apps", "available_apps": "Verfügbare Apps",
"available_apps_lower_case": "Verfügbare Apps",
"available_apps_desc": "Sie haben keine Apps installiert. Sehen Sie sich beliebte Apps unten an und entdecken Sie noch mehr in unserem <1>App Store</1>",
"check_email_reset_password": "Überprüfen Sie Ihre E-Mail. Wir haben Ihnen einen Link zum Zurücksetzen Ihres Passworts gesendet.", "check_email_reset_password": "Überprüfen Sie Ihre E-Mail. Wir haben Ihnen einen Link zum Zurücksetzen Ihres Passworts gesendet.",
"finish": "Fertig", "finish": "Fertig",
"organization_general_description": "Einstellungen für die Sprache und Zeitzone Ihres Teams verwalten", "organization_general_description": "Einstellungen für die Sprache und Zeitzone Ihres Teams verwalten",
@@ -406,6 +409,7 @@
"booking_requested": "Buchung angefragt", "booking_requested": "Buchung angefragt",
"meeting_ended": "Meeting beendet", "meeting_ended": "Meeting beendet",
"form_submitted": "Formular gesendet", "form_submitted": "Formular gesendet",
"booking_paid": "Buchung bezahlt",
"event_triggers": "Event-Auslöser", "event_triggers": "Event-Auslöser",
"subscriber_url": "Subscriber-URL", "subscriber_url": "Subscriber-URL",
"create_new_webhook": "Einen neuen Webhook erstellen", "create_new_webhook": "Einen neuen Webhook erstellen",
@@ -1864,6 +1868,9 @@
"open_dialog_with_element_click": "Öffnet Ihren Cal-Dialog, wenn jemand ein Bedienelement anklickt.", "open_dialog_with_element_click": "Öffnet Ihren Cal-Dialog, wenn jemand ein Bedienelement anklickt.",
"need_help_embedding": "Brauchen Sie Hilfe? Sehen Sie sich unsere Anleitungen zum Einbetten von Cal auf Wix, Squarespace, oder WordPress an, schauen Sie sich unsere häufig gestellten Fragen an oder erkunden Sie erweiterte Einbettungsoptionen.", "need_help_embedding": "Brauchen Sie Hilfe? Sehen Sie sich unsere Anleitungen zum Einbetten von Cal auf Wix, Squarespace, oder WordPress an, schauen Sie sich unsere häufig gestellten Fragen an oder erkunden Sie erweiterte Einbettungsoptionen.",
"book_my_cal": "Mich per Cal buchen", "book_my_cal": "Mich per Cal buchen",
"first_name": "Vorname",
"last_name": "Nachname",
"first_last_name": "Vorname, Nachname",
"invite_as": "Einladen als", "invite_as": "Einladen als",
"form_updated_successfully": "Formular erfolgreich aktualisiert.", "form_updated_successfully": "Formular erfolgreich aktualisiert.",
"disable_attendees_confirmation_emails": "Standardmäßige Bestätigungs-E-Mails für Teilnehmer deaktivieren", "disable_attendees_confirmation_emails": "Standardmäßige Bestätigungs-E-Mails für Teilnehmer deaktivieren",
@@ -1939,5 +1946,6 @@
"insights_user_filter": "Benutzer: {{userName}}", "insights_user_filter": "Benutzer: {{userName}}",
"insights_subtitle": "Sehen Sie sich Buchungs-Insights über Ihre Termine an", "insights_subtitle": "Sehen Sie sich Buchungs-Insights über Ihre Termine an",
"custom_plan": "Benutzerdefinierter Plan", "custom_plan": "Benutzerdefinierter Plan",
"org_max_team_warnings": "Weitere Teams können Sie zu einem späteren Zeitpunkt hinzufügen.",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Fügen Sie Ihre neuen Zeichenketten über dieser hinzu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Fügen Sie Ihre neuen Zeichenketten über dieser hinzu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -244,6 +244,8 @@
"all": "All", "all": "All",
"yours": "Your account", "yours": "Your account",
"available_apps": "Available Apps", "available_apps": "Available Apps",
"available_apps_lower_case": "Available apps",
"available_apps_desc": "You have no apps installed. View popular apps below and explore more in our <1>App Store</1>",
"check_email_reset_password": "Check your email. We sent you a link to reset your password.", "check_email_reset_password": "Check your email. We sent you a link to reset your password.",
"finish": "Finish", "finish": "Finish",
"organization_general_description": "Manage settings for your team language and timezone", "organization_general_description": "Manage settings for your team language and timezone",
@@ -407,6 +409,7 @@
"booking_requested": "Booking Requested", "booking_requested": "Booking Requested",
"meeting_ended": "Meeting Ended", "meeting_ended": "Meeting Ended",
"form_submitted": "Form Submitted", "form_submitted": "Form Submitted",
"booking_paid": "Booking Paid",
"event_triggers": "Event Triggers", "event_triggers": "Event Triggers",
"subscriber_url": "Subscriber URL", "subscriber_url": "Subscriber URL",
"create_new_webhook": "Create a new webhook", "create_new_webhook": "Create a new webhook",
@@ -1867,6 +1870,9 @@
"open_dialog_with_element_click": "Open your Cal dialog when someone clicks an element.", "open_dialog_with_element_click": "Open your Cal dialog when someone clicks an element.",
"need_help_embedding": "Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options.", "need_help_embedding": "Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options.",
"book_my_cal": "Book my Cal", "book_my_cal": "Book my Cal",
"first_name": "First name",
"last_name": "Last name",
"first_last_name": "First name, Last name",
"invite_as": "Invite as", "invite_as": "Invite as",
"form_updated_successfully": "Form updated successfully.", "form_updated_successfully": "Form updated successfully.",
"disable_attendees_confirmation_emails": "Disable default confirmation emails for attendees", "disable_attendees_confirmation_emails": "Disable default confirmation emails for attendees",
+176 -1
View File
@@ -129,6 +129,8 @@
"team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.", "team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.",
"upgrade_banner_action": "Actualizar aquí", "upgrade_banner_action": "Actualizar aquí",
"team_upgraded_successfully": "¡Tu equipo se actualizó con éxito!", "team_upgraded_successfully": "¡Tu equipo se actualizó con éxito!",
"org_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.",
"org_upgraded_successfully": "Su organización se actualizó con éxito.",
"use_link_to_reset_password": "Utilice el enlace de abajo para restablecer su contraseña", "use_link_to_reset_password": "Utilice el enlace de abajo para restablecer su contraseña",
"hey_there": "Hola,", "hey_there": "Hola,",
"forgot_your_password_calcom": "¿Olvidaste tu contraseña? - {{appName}}", "forgot_your_password_calcom": "¿Olvidaste tu contraseña? - {{appName}}",
@@ -195,6 +197,7 @@
"blog": "Blog", "blog": "Blog",
"blog_description": "Lee nuestras últimas noticias y artículos", "blog_description": "Lee nuestras últimas noticias y artículos",
"join_our_community": "Únete a nuestra comunidad", "join_our_community": "Únete a nuestra comunidad",
"join_our_discord": "Únase a nuestro Discord",
"404_claim_entity_user": "Reclama tu nombre de usuario y programa eventos", "404_claim_entity_user": "Reclama tu nombre de usuario y programa eventos",
"popular_pages": "Páginas Populares", "popular_pages": "Páginas Populares",
"register_now": "Regístrate Ahora", "register_now": "Regístrate Ahora",
@@ -202,6 +205,7 @@
"page_doesnt_exist": "Esta página no existe.", "page_doesnt_exist": "Esta página no existe.",
"check_spelling_mistakes_or_go_back": "Comprueba errores ortográficos o vuelve a la página anterior.", "check_spelling_mistakes_or_go_back": "Comprueba errores ortográficos o vuelve a la página anterior.",
"404_page_not_found": "404: Esta página no se ha encontrado.", "404_page_not_found": "404: Esta página no se ha encontrado.",
"booker_event_not_found": "No pudimos encontrar el evento que está intentando reservar.",
"getting_started": "Empezar", "getting_started": "Empezar",
"15min_meeting": "Reunión de 15 min", "15min_meeting": "Reunión de 15 min",
"30min_meeting": "Reunión de 30 min", "30min_meeting": "Reunión de 30 min",
@@ -237,11 +241,14 @@
"done": "Hecho", "done": "Hecho",
"all_done": "¡Todo listo!", "all_done": "¡Todo listo!",
"all": "Todas las aplicaciones", "all": "Todas las aplicaciones",
"yours": "Su cuenta",
"available_apps": "Aplicaciones disponibles", "available_apps": "Aplicaciones disponibles",
"check_email_reset_password": "Revisa tu email. Te hemos enviado un enlace para restablecer tu contraseña.", "check_email_reset_password": "Revisa tu email. Te hemos enviado un enlace para restablecer tu contraseña.",
"finish": "Terminar", "finish": "Terminar",
"organization_general_description": "Administre los ajustes para el idioma y la zona horaria de su equipo",
"few_sentences_about_yourself": "Unas pocas frases sobre ti mismo. Esto aparecerá en tu página de url personal.", "few_sentences_about_yourself": "Unas pocas frases sobre ti mismo. Esto aparecerá en tu página de url personal.",
"nearly_there": "¡Ya casi está!", "nearly_there": "¡Ya casi está!",
"nearly_there_instructions": "Lo último, una breve descripción sobre usted y una foto realmente lo ayudan a obtener reservas y a que las personas sepan con quién están reservando.",
"set_availability_instructions": "Defina los intervalos de tiempo cuando esté disponible de forma recurrente. Puede crear más tarde y asignarlos a diferentes calendarios.", "set_availability_instructions": "Defina los intervalos de tiempo cuando esté disponible de forma recurrente. Puede crear más tarde y asignarlos a diferentes calendarios.",
"set_availability": "Establecer Disponibilidad", "set_availability": "Establecer Disponibilidad",
"continue_without_calendar": "Continuar sin calendario", "continue_without_calendar": "Continuar sin calendario",
@@ -297,6 +304,18 @@
"success": "Éxito", "success": "Éxito",
"failed": "Falló", "failed": "Falló",
"password_has_been_reset_login": "Su contraseña ha sido restablecida. Ahora puede iniciar sesión con su nueva contraseña.", "password_has_been_reset_login": "Su contraseña ha sido restablecida. Ahora puede iniciar sesión con su nueva contraseña.",
"layout": "Diseño",
"bookerlayout_default_title": "Vista predeterminada",
"bookerlayout_description": "Puede seleccionar varios y sus reservadores pueden cambiar de vista.",
"bookerlayout_user_settings_title": "Diseño de reserva",
"bookerlayout_user_settings_description": "Puede seleccionar varios y los reservadores pueden cambiar de vista. Esto se puede anular por evento.",
"bookerlayout_month_view": "Mes",
"bookerlayout_week_view": "Semanal",
"bookerlayout_column_view": "Columna",
"bookerlayout_error_min_one_enabled": "Al menos un diseño tiene que estar habilitado.",
"bookerlayout_error_default_not_enabled": "El diseño que seleccionó como vista predeterminada no es parte de los diseños habilitados.",
"bookerlayout_error_unknown_layout": "El diseño seleccionado no es un diseño válido.",
"bookerlayout_override_global_settings": "Puede gestionar esto para todos sus tipos de eventos en <2>configuración / apariencia</2> o <6>sobrescribir solo para este evento</6>.",
"unexpected_error_try_again": "Ocurrió un error inesperado. Inténtelo de nuevo.", "unexpected_error_try_again": "Ocurrió un error inesperado. Inténtelo de nuevo.",
"sunday_time_error": "Hora inválida del domingo", "sunday_time_error": "Hora inválida del domingo",
"monday_time_error": "Hora inválida del lunes", "monday_time_error": "Hora inválida del lunes",
@@ -309,6 +328,7 @@
"error_end_time_next_day": "La hora final no puede ser mayor de 24 horas", "error_end_time_next_day": "La hora final no puede ser mayor de 24 horas",
"back_to_bookings": "Volver a Reservas", "back_to_bookings": "Volver a Reservas",
"free_to_pick_another_event_type": "No dude en elegir otro evento en cualquier momento.", "free_to_pick_another_event_type": "No dude en elegir otro evento en cualquier momento.",
"cancelled": "Cancelado",
"cancellation_successful": "Cancelación Realizada", "cancellation_successful": "Cancelación Realizada",
"really_cancel_booking": "¿Realmente deseas cancelar tu reserva?", "really_cancel_booking": "¿Realmente deseas cancelar tu reserva?",
"cannot_cancel_booking": "No puedes cancelar esta reserva", "cannot_cancel_booking": "No puedes cancelar esta reserva",
@@ -317,6 +337,12 @@
"cancelling_event_recurring": "El evento es un caso de un evento recurrente.", "cancelling_event_recurring": "El evento es un caso de un evento recurrente.",
"cancelling_all_recurring": "Todas estas son instancias restantes en el evento recurrente.", "cancelling_all_recurring": "Todas estas son instancias restantes en el evento recurrente.",
"error_with_status_code_occured": "Se produjo un error con el código de estado {{status}}.", "error_with_status_code_occured": "Se produjo un error con el código de estado {{status}}.",
"error_event_type_url_duplicate": "Ya existe un tipo de evento con esta URL.",
"error_event_type_unauthorized_create": "No puede crear este evento",
"error_event_type_unauthorized_update": "No puede editar este evento",
"error_workflow_unauthorized_create": "No puede crear este flujo de trabajo",
"error_schedule_unauthorized_create": "No puede crear este programa",
"booking_already_cancelled": "Esta reserva ya se canceló",
"booking_already_accepted_rejected": "Esta reserva ya se aceptó o rechazó", "booking_already_accepted_rejected": "Esta reserva ya se aceptó o rechazó",
"go_back_home": "Volver a Inicio", "go_back_home": "Volver a Inicio",
"or_go_back_home": "O Volver al Inicio", "or_go_back_home": "O Volver al Inicio",
@@ -326,10 +352,12 @@
"no_status_bookings_yet_description": "No tienes {{status}} reservas. {{description}}", "no_status_bookings_yet_description": "No tienes {{status}} reservas. {{description}}",
"event_between_users": "{{eventName}} entre {{host}} y {{attendeeName}}", "event_between_users": "{{eventName}} entre {{host}} y {{attendeeName}}",
"bookings": "Reservas", "bookings": "Reservas",
"booking_not_found": "Reserva no encontrada",
"bookings_description": "Vea eventos futuros y pasados reservados a través de sus enlaces de tipo de eventos.", "bookings_description": "Vea eventos futuros y pasados reservados a través de sus enlaces de tipo de eventos.",
"upcoming_bookings": "Tan pronto como alguien reserve una hora contigo, aparecerá aquí.", "upcoming_bookings": "Tan pronto como alguien reserve una hora contigo, aparecerá aquí.",
"recurring_bookings": "Tan pronto como alguien reserve una reunión recurrente con usted, aparecerá aquí.", "recurring_bookings": "Tan pronto como alguien reserve una reunión recurrente con usted, aparecerá aquí.",
"past_bookings": "Sus reservas pasadas aparecerán aquí.", "past_bookings": "Sus reservas pasadas aparecerán aquí.",
"cancelled_bookings": "Las reservas canceladas aparecerán aquí.",
"unconfirmed_bookings": "Las reservas sin confirmar aparecerán aquí.", "unconfirmed_bookings": "Las reservas sin confirmar aparecerán aquí.",
"unconfirmed_bookings_tooltip": "Reservas sin confirmar", "unconfirmed_bookings_tooltip": "Reservas sin confirmar",
"on": "en", "on": "en",
@@ -363,15 +391,19 @@
"user_dynamic_booking_disabled": "Actualmente, algunos de los usuarios del grupo tienen desactivadas las reservas dinámicas grupales", "user_dynamic_booking_disabled": "Actualmente, algunos de los usuarios del grupo tienen desactivadas las reservas dinámicas grupales",
"allow_dynamic_booking_tooltip": "Los enlaces de reservas grupales se pueden crear dinámicamente añadiendo varios nombres de usuario con un '+'. Ejemplo: '{{appName}}/bailey+peer'", "allow_dynamic_booking_tooltip": "Los enlaces de reservas grupales se pueden crear dinámicamente añadiendo varios nombres de usuario con un '+'. Ejemplo: '{{appName}}/bailey+peer'",
"allow_dynamic_booking": "Permitir que los asistentes lo reserven a través de reservas dinámicas de grupo", "allow_dynamic_booking": "Permitir que los asistentes lo reserven a través de reservas dinámicas de grupo",
"dynamic_booking": "Enlaces dinámicos de grupo",
"email": "Correo electrónico", "email": "Correo electrónico",
"email_placeholder": "nombre@ejemplo.com", "email_placeholder": "nombre@ejemplo.com",
"full_name": "Nombre Completo", "full_name": "Nombre Completo",
"browse_api_documentation": "Consulte la documentación de nuestra API", "browse_api_documentation": "Consulte la documentación de nuestra API",
"leverage_our_api": "Aproveche nuestra API para un control total y personalización.", "leverage_our_api": "Aproveche nuestra API para un control total y personalización.",
"create_webhook": "Crear Webhook", "create_webhook": "Crear Webhook",
"booking_cancelled": "Reserva cancelada",
"booking_rescheduled": "Reserva habilitada", "booking_rescheduled": "Reserva habilitada",
"recording_ready": "Enlace de descarga de grabación listo", "recording_ready": "Enlace de descarga de grabación listo",
"booking_created": "Reserva Creada", "booking_created": "Reserva Creada",
"booking_rejected": "Reserva rechazada",
"booking_requested": "Reserva solicitada",
"meeting_ended": "Reunión finalizada", "meeting_ended": "Reunión finalizada",
"form_submitted": "Formulario enviado", "form_submitted": "Formulario enviado",
"event_triggers": "Activadores de Eventos", "event_triggers": "Activadores de Eventos",
@@ -381,6 +413,8 @@
"team_webhooks": "Webhooks del equipo", "team_webhooks": "Webhooks del equipo",
"create_new_webhook_to_account": "Crear un nuevo webhook en tu cuenta", "create_new_webhook_to_account": "Crear un nuevo webhook en tu cuenta",
"new_webhook": "Nuevo Webhook", "new_webhook": "Nuevo Webhook",
"receive_cal_meeting_data": "Reciba datos de reuniones de {{appName}} en una URL específica, en tiempo real, cuando se programe o cancele un evento.",
"receive_cal_event_meeting_data": "Reciba datos de reuniones de {{appName}} en una URL específica, en tiempo real, cuando se programe o cancele un evento.",
"responsive_fullscreen_iframe": "Iframe receptivo a pantalla completa", "responsive_fullscreen_iframe": "Iframe receptivo a pantalla completa",
"loading": "Cargando...", "loading": "Cargando...",
"deleting": "Eliminando...", "deleting": "Eliminando...",
@@ -443,6 +477,7 @@
"max_limit_allowed_hint": "Debe tener {{limit}} o menos caracteres", "max_limit_allowed_hint": "Debe tener {{limit}} o menos caracteres",
"invalid_password_hint": "La contraseña debe tener un mínimo de {{passwordLength}} caracteres que contengan al menos un número y una mezcla de letras mayúsculas y minúsculas", "invalid_password_hint": "La contraseña debe tener un mínimo de {{passwordLength}} caracteres que contengan al menos un número y una mezcla de letras mayúsculas y minúsculas",
"incorrect_password": "La Contraseña es Incorrecta.", "incorrect_password": "La Contraseña es Incorrecta.",
"incorrect_email_password": "El correo electrónico o la contraseña son incorrectos.",
"use_setting": "Usar Ajuste", "use_setting": "Usar Ajuste",
"am_pm": "am/pm", "am_pm": "am/pm",
"time_options": "Opciones Horas", "time_options": "Opciones Horas",
@@ -470,6 +505,7 @@
"additional_guests": "Añadir invitados", "additional_guests": "Añadir invitados",
"your_name": "Tu Nombre", "your_name": "Tu Nombre",
"your_full_name": "Su nombre completo", "your_full_name": "Su nombre completo",
"no_name": "Sin nombre",
"email_address": "Email", "email_address": "Email",
"enter_valid_email": "Ingresa un correo electrónico válido", "enter_valid_email": "Ingresa un correo electrónico válido",
"location": "Ubicación", "location": "Ubicación",
@@ -513,10 +549,13 @@
"your_team_updated_successfully": "Tu equipo ha sido actualizado con éxito.", "your_team_updated_successfully": "Tu equipo ha sido actualizado con éxito.",
"about": "Acerca de", "about": "Acerca de",
"team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.", "team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.",
"org_description": "Algunas frases sobre su organización. Esto aparecerá en la página de la URL de su organización.",
"members": "Miembros", "members": "Miembros",
"organization_members": "Miembros de la organización",
"member": "Miembro", "member": "Miembro",
"number_member_one": "{{count}} miembro", "number_member_one": "{{count}} miembro",
"number_member_other": "{{count}} miembros", "number_member_other": "{{count}} miembros",
"number_selected": "{{count}} seleccionados",
"owner": "Propietario", "owner": "Propietario",
"admin": "Administrador", "admin": "Administrador",
"administrator_user": "Usuario administrador", "administrator_user": "Usuario administrador",
@@ -547,6 +586,8 @@
"confirm_all": "Confirmar todo", "confirm_all": "Confirmar todo",
"disband_team": "Disolver Equipo", "disband_team": "Disolver Equipo",
"disband_team_confirmation_message": "¿Estás seguro de que quieres disolver este equipo? Cualquiera con quien has compartido este enlace de equipo ya no podrá reservar usando el mismo.", "disband_team_confirmation_message": "¿Estás seguro de que quieres disolver este equipo? Cualquiera con quien has compartido este enlace de equipo ya no podrá reservar usando el mismo.",
"disband_org": "Disolver la organización",
"disband_org_confirmation_message": "¿Está seguro de que desea disolver esta organización? Todos los equipos y miembros se eliminarán.",
"remove_member_confirmation_message": "¿Estás seguro de que quieres eliminar este miembro del equipo?", "remove_member_confirmation_message": "¿Estás seguro de que quieres eliminar este miembro del equipo?",
"confirm_disband_team": "Sí, Disolver Equipo", "confirm_disband_team": "Sí, Disolver Equipo",
"confirm_remove_member": "Sí, Eliminar Miembro", "confirm_remove_member": "Sí, Eliminar Miembro",
@@ -621,6 +662,7 @@
"event_type_updated_successfully": "{{eventTypeTitle}} tipo de evento actualizado con éxito", "event_type_updated_successfully": "{{eventTypeTitle}} tipo de evento actualizado con éxito",
"event_type_deleted_successfully": "Tipo de evento eliminado con éxito", "event_type_deleted_successfully": "Tipo de evento eliminado con éxito",
"hours": "Horas", "hours": "Horas",
"people": "Personas",
"your_email": "Tu Email", "your_email": "Tu Email",
"change_avatar": "Cambiar Avatar", "change_avatar": "Cambiar Avatar",
"language": "Lenguaje", "language": "Lenguaje",
@@ -653,9 +695,11 @@
"create_new_team": "Crear Nuevo Equipo", "create_new_team": "Crear Nuevo Equipo",
"open_invitations": "Invitaciones Abiertas", "open_invitations": "Invitaciones Abiertas",
"new_team": "Nuevo Equipo", "new_team": "Nuevo Equipo",
"create_first_team_and_invite_others": "Cree su primer equipo e invite a otros usuarios a trabajar juntos.",
"create_team_to_get_started": "Crea un equipo para empezar", "create_team_to_get_started": "Crea un equipo para empezar",
"teams": "Equipos", "teams": "Equipos",
"team": "Equipo", "team": "Equipo",
"organization": "Organización",
"team_billing": "Facturación del equipo", "team_billing": "Facturación del equipo",
"team_billing_description": "Gestione la facturación para su equipo", "team_billing_description": "Gestione la facturación para su equipo",
"upgrade_to_flexible_pro_title": "Hemos cambiado la facturación de los equipos", "upgrade_to_flexible_pro_title": "Hemos cambiado la facturación de los equipos",
@@ -730,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}} proporcionará una URL de la videollamada de Huddle01 Web3.", "cal_provide_huddle01_meeting_url": "{{appName}} proporcionará una URL de la videollamada de Huddle01 Web3.",
"cal_provide_teams_meeting_url": "{{appName}} proporcionará una URL de reunión de MS Teams. NOTA: DEBE TENER UNA CUENTA DE TRABAJO O INSTITUCIÓN", "cal_provide_teams_meeting_url": "{{appName}} proporcionará una URL de reunión de MS Teams. NOTA: DEBE TENER UNA CUENTA DE TRABAJO O INSTITUCIÓN",
"require_payment": "Requiere Pago", "require_payment": "Requiere Pago",
"you_need_to_add_a_name": "Necesita agregar un nombre",
"commission_per_transaction": "Comisión por Transacción", "commission_per_transaction": "Comisión por Transacción",
"event_type_updated_successfully_description": "Tu Evento fue Actualizado con Éxito.", "event_type_updated_successfully_description": "Tu Evento fue Actualizado con Éxito.",
"hide_event_type": "Ocultar Tipo de Evento", "hide_event_type": "Ocultar Tipo de Evento",
@@ -820,18 +865,25 @@
"installed_apps": "Aplicaciones instaladas", "installed_apps": "Aplicaciones instaladas",
"free_to_use_apps": "Gratis", "free_to_use_apps": "Gratis",
"no_category_apps": "No hay aplicaciones de {{category}}", "no_category_apps": "No hay aplicaciones de {{category}}",
"all_apps": "Todas las aplicaciones",
"no_category_apps_description_calendar": "Añade una aplicación de calendario para comprobar si hay conflictos y evitar reservas duplicadas", "no_category_apps_description_calendar": "Añade una aplicación de calendario para comprobar si hay conflictos y evitar reservas duplicadas",
"no_category_apps_description_conferencing": "Intente agregar una aplicación de conferencia para videollamadas con sus clientes",
"no_category_apps_description_payment": "Añade una aplicación de pagos para facilitar las transacciones con tus clientes", "no_category_apps_description_payment": "Añade una aplicación de pagos para facilitar las transacciones con tus clientes",
"no_category_apps_description_analytics": "Añada una aplicación de análisis para sus páginas de reserva", "no_category_apps_description_analytics": "Añada una aplicación de análisis para sus páginas de reserva",
"no_category_apps_description_automation": "Añada una aplicación de automatización para utilizar", "no_category_apps_description_automation": "Añada una aplicación de automatización para utilizar",
"no_category_apps_description_other": "Añade cualquier otro tipo de aplicación para hacer todo tipo de tareas", "no_category_apps_description_other": "Añade cualquier otro tipo de aplicación para hacer todo tipo de tareas",
"no_category_apps_description_web3": "Agregue una aplicación web3 para sus páginas de reserva", "no_category_apps_description_web3": "Agregue una aplicación web3 para sus páginas de reserva",
"no_category_apps_description_messaging": "Agregue una aplicación de mensajería para configurar notificaciones y recordatorios personalizados",
"no_category_apps_description_crm": "Agregue una aplicación CRM para realizar un seguimiento de con quiénes se ha reunido",
"installed_app_calendar_description": "Configure el(los) calendario(s) para comprobar conflictos y evitar reservas duplicadas.", "installed_app_calendar_description": "Configure el(los) calendario(s) para comprobar conflictos y evitar reservas duplicadas.",
"installed_app_payment_description": "Configura los servicios de procesamiento de pagos que vas a utilizar para cobrar a tus clientes.", "installed_app_payment_description": "Configura los servicios de procesamiento de pagos que vas a utilizar para cobrar a tus clientes.",
"installed_app_analytics_description": "Configure qué aplicaciones de análisis va a utilizar para sus páginas de reserva", "installed_app_analytics_description": "Configure qué aplicaciones de análisis va a utilizar para sus páginas de reserva",
"installed_app_other_description": "Todas tus aplicaciones instaladas de otras categorías.", "installed_app_other_description": "Todas tus aplicaciones instaladas de otras categorías.",
"installed_app_conferencing_description": "Configure qué aplicaciones de conferencia usará",
"installed_app_automation_description": "Configure qué aplicaciones de automatización va a utilizar", "installed_app_automation_description": "Configure qué aplicaciones de automatización va a utilizar",
"installed_app_web3_description": "Configure qué aplicaciones web3 usar para sus páginas de reserva", "installed_app_web3_description": "Configure qué aplicaciones web3 usar para sus páginas de reserva",
"installed_app_messaging_description": "Configure qué aplicaciones de mensajería usar para configurar notificaciones y recordatorios personalizados",
"installed_app_crm_description": "Configure qué aplicaciones de CRM usar para realizar un seguimiento de las personas con las que se ha reunido",
"analytics": "Análisis", "analytics": "Análisis",
"empty_installed_apps_headline": "No hay aplicaciones instaladas", "empty_installed_apps_headline": "No hay aplicaciones instaladas",
"empty_installed_apps_description": "Las aplicaciones te permiten mejorar significativamente tu flujo de trabajo y mejorar tu agendamiento.", "empty_installed_apps_description": "Las aplicaciones te permiten mejorar significativamente tu flujo de trabajo y mejorar tu agendamiento.",
@@ -857,6 +909,7 @@
"create_events_on": "Crear eventos en", "create_events_on": "Crear eventos en",
"enterprise_license": "Esta es una función empresarial", "enterprise_license": "Esta es una función empresarial",
"enterprise_license_description": "Para habilitar esta función, obtenga una clave de despliegue en la consola {{consoleUrl}} y añádala a su .env como CALCOM_LICENSE_KEY. Si su equipo ya tiene una licencia, póngase en contacto con {{supportMail}} para obtener ayuda.", "enterprise_license_description": "Para habilitar esta función, obtenga una clave de despliegue en la consola {{consoleUrl}} y añádala a su .env como CALCOM_LICENSE_KEY. Si su equipo ya tiene una licencia, póngase en contacto con {{supportMail}} para obtener ayuda.",
"enterprise_license_development": "Puede probar esta función en el modo de desarrollo. Para el uso de producción, haga que un administrador vaya a <2>/auth/setup</2> para ingresar una clave de licencia.",
"missing_license": "Falta la licencia", "missing_license": "Falta la licencia",
"signup_requires": "Licencia comercial requerida", "signup_requires": "Licencia comercial requerida",
"signup_requires_description": "Actualmente, {{companyName}} no ofrece una versión gratuita de código abierto de la página de registro. Para recibir acceso completo a los componentes de registro es necesario adquirir una licencia comercial. Para uso personal, recomendamos la Plataforma de Datos Prisma o cualquier otra interfaz Postgres para crear cuentas.", "signup_requires_description": "Actualmente, {{companyName}} no ofrece una versión gratuita de código abierto de la página de registro. Para recibir acceso completo a los componentes de registro es necesario adquirir una licencia comercial. Para uso personal, recomendamos la Plataforma de Datos Prisma o cualquier otra interfaz Postgres para crear cuentas.",
@@ -926,6 +979,7 @@
"confirm_delete_api_key": "Revocar esta clave API", "confirm_delete_api_key": "Revocar esta clave API",
"revoke_api_key": "Revocar clave API", "revoke_api_key": "Revocar clave API",
"api_key_copied": "¡Clave API copiada!", "api_key_copied": "¡Clave API copiada!",
"api_key_expires_on": "La clave API caducará el",
"delete_api_key_confirm_title": "¿Eliminar permanentemente esta clave de API de tu cuenta?", "delete_api_key_confirm_title": "¿Eliminar permanentemente esta clave de API de tu cuenta?",
"copy": "Copiar", "copy": "Copiar",
"expire_date": "Fecha de caducidad", "expire_date": "Fecha de caducidad",
@@ -948,6 +1002,9 @@
"user_impersonation_heading": "Suplantación de usuario", "user_impersonation_heading": "Suplantación de usuario",
"user_impersonation_description": "Permite a nuestro equipo de soporte iniciar sesión temporalmente para ayudar a resolver rápidamente cualquier problema reportado.", "user_impersonation_description": "Permite a nuestro equipo de soporte iniciar sesión temporalmente para ayudar a resolver rápidamente cualquier problema reportado.",
"team_impersonation_description": "Permita a los administradores de su equipo iniciar sesión temporalmente como usted.", "team_impersonation_description": "Permita a los administradores de su equipo iniciar sesión temporalmente como usted.",
"make_team_private": "Hacer que el equipo sea privado",
"make_team_private_description": "Los miembros de su equipo no podrán ver a otros miembros del equipo cuando esto esté activado.",
"you_cannot_see_team_members": "No puede ver a todos los miembros de un equipo privado.",
"allow_booker_to_select_duration": "Permitir que el encargado de las reservas seleccione la duración", "allow_booker_to_select_duration": "Permitir que el encargado de las reservas seleccione la duración",
"impersonate_user_tip": "Todos los usos de esta función son revisados.", "impersonate_user_tip": "Todos los usos de esta función son revisados.",
"impersonating_user_warning": "Suplantando nombre de usuario \"{{user}}\".", "impersonating_user_warning": "Suplantando nombre de usuario \"{{user}}\".",
@@ -1015,16 +1072,21 @@
"event_location": "Ubicación del evento", "event_location": "Ubicación del evento",
"reschedule_optional": "Razón para reagendar (opcional)", "reschedule_optional": "Razón para reagendar (opcional)",
"reschedule_placeholder": "Informa a los demás la razón por la que necesitas reagendar", "reschedule_placeholder": "Informa a los demás la razón por la que necesitas reagendar",
"event_cancelled": "Este evento se canceló",
"emailed_information_about_cancelled_event": "Le enviamos un correo electrónico a usted y a los demás asistentes para informarles.", "emailed_information_about_cancelled_event": "Le enviamos un correo electrónico a usted y a los demás asistentes para informarles.",
"this_input_will_shown_booking_this_event": "Esta entrada se mostrará al reservar este evento.", "this_input_will_shown_booking_this_event": "Esta entrada se mostrará al reservar este evento.",
"meeting_url_in_conformation_email": "La URL de la reunión está en el correo de confirmación", "meeting_url_in_conformation_email": "La URL de la reunión está en el correo de confirmación",
"url_start_with_https": "La URL debe empezar por http:// o https://", "url_start_with_https": "La URL debe empezar por http:// o https://",
"number_provided": "Se proporcionará el número de teléfono", "number_provided": "Se proporcionará el número de teléfono",
"before_event_trigger": "antes del inicio del evento", "before_event_trigger": "antes del inicio del evento",
"event_cancelled_trigger": "cuando se cancela el evento",
"new_event_trigger": "cuando se reserva un nuevo evento", "new_event_trigger": "cuando se reserva un nuevo evento",
"email_host_action": "enviar correo electrónico al anfitrión", "email_host_action": "enviar correo electrónico al anfitrión",
"email_attendee_action": "enviar correo electrónico a los asistentes", "email_attendee_action": "enviar correo electrónico a los asistentes",
"sms_attendee_action": "Enviar un SMS al asistente",
"sms_number_action": "enviar SMS a un número específico", "sms_number_action": "enviar SMS a un número específico",
"whatsapp_number_action": "enviar un mensaje de Whatsapp a un número específico",
"whatsapp_attendee_action": "enviar un mensae de Whatsapp al asistente",
"workflows": "Flujos de trabajo", "workflows": "Flujos de trabajo",
"new_workflow_btn": "Flujo de trabajo nuevo", "new_workflow_btn": "Flujo de trabajo nuevo",
"add_new_workflow": "Agregar un flujo de trabajo nuevo", "add_new_workflow": "Agregar un flujo de trabajo nuevo",
@@ -1088,6 +1150,8 @@
"choose_template": "Elija una plantilla", "choose_template": "Elija una plantilla",
"custom": "Personalizado", "custom": "Personalizado",
"reminder": "Recordatorio", "reminder": "Recordatorio",
"rescheduled": "Reprogramado",
"completed": "Completado",
"reminder_email": "Recordatorio: {{eventType}} con {{name}} el {{date}}", "reminder_email": "Recordatorio: {{eventType}} con {{name}} el {{date}}",
"not_triggering_existing_bookings": "No se activará para las reservas ya existentes, ya que se le pedirá al usuario un número de teléfono al reservar el evento.", "not_triggering_existing_bookings": "No se activará para las reservas ya existentes, ya que se le pedirá al usuario un número de teléfono al reservar el evento.",
"minute_one": "{{count}} minuto", "minute_one": "{{count}} minuto",
@@ -1185,6 +1249,7 @@
"start_of_week": "Inicio de la semana", "start_of_week": "Inicio de la semana",
"recordings_title": "Grabaciones", "recordings_title": "Grabaciones",
"recording": "Grabación", "recording": "Grabación",
"happy_scheduling": "Feliz programación",
"select_calendars": "Seleccione los calendarios en los que desee comprobar conflictos para evitar reservas dobles.", "select_calendars": "Seleccione los calendarios en los que desee comprobar conflictos para evitar reservas dobles.",
"check_for_conflicts": "Comprobar conflictos", "check_for_conflicts": "Comprobar conflictos",
"view_recordings": "Ver grabaciones", "view_recordings": "Ver grabaciones",
@@ -1226,6 +1291,7 @@
"conferencing_description": "Añada sus aplicaciones de videoconferencia favoritas para sus reuniones", "conferencing_description": "Añada sus aplicaciones de videoconferencia favoritas para sus reuniones",
"add_conferencing_app": "Añadir aplicación de conferencia", "add_conferencing_app": "Añadir aplicación de conferencia",
"password_description": "Administra los ajustes para las contraseñas de tu cuenta", "password_description": "Administra los ajustes para las contraseñas de tu cuenta",
"set_up_two_factor_authentication": "Configure su autenticación de doble factor",
"we_just_need_basic_info": "Solo necesitamos información básica para configurar tu perfil.", "we_just_need_basic_info": "Solo necesitamos información básica para configurar tu perfil.",
"skip": "Omitir", "skip": "Omitir",
"do_this_later": "Hacerlo más tarde", "do_this_later": "Hacerlo más tarde",
@@ -1239,6 +1305,8 @@
"connect_analytics_apps": "Conecte aplicaciones de análisis", "connect_analytics_apps": "Conecte aplicaciones de análisis",
"connect_other_apps": "Conectar otras aplicaciones", "connect_other_apps": "Conectar otras aplicaciones",
"connect_web3_apps": "Conectar aplicaciones web3", "connect_web3_apps": "Conectar aplicaciones web3",
"connect_messaging_apps": "Conectar aplicaciones de mensajería",
"connect_crm_apps": "Conectar aplicaciones CRM",
"current_step_of_total": "Paso {{currentStep}} de {{maxSteps}}", "current_step_of_total": "Paso {{currentStep}} de {{maxSteps}}",
"add_variable": "Añadir variable", "add_variable": "Añadir variable",
"custom_phone_number": "Número de teléfono personalizado", "custom_phone_number": "Número de teléfono personalizado",
@@ -1251,12 +1319,14 @@
"location_info": "Ubicación del evento", "location_info": "Ubicación del evento",
"additional_notes_info": "Notas adicionales de la reserva", "additional_notes_info": "Notas adicionales de la reserva",
"attendee_name_info": "Nombre de la persona que reserva", "attendee_name_info": "Nombre de la persona que reserva",
"organizer_name_info": "Nombre del organizador",
"to": "Para", "to": "Para",
"workflow_turned_on_successfully": "El flujo de trabajo {{workflowName}} se ha activado {{offOn}} con éxito", "workflow_turned_on_successfully": "El flujo de trabajo {{workflowName}} se ha activado {{offOn}} con éxito",
"download_responses": "Descargar respuestas", "download_responses": "Descargar respuestas",
"download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.", "download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.",
"download": "Descargar", "download": "Descargar",
"download_recording": "Descargar grabación", "download_recording": "Descargar grabación",
"recording_from_your_recent_call": "Una grabación de su llamada reciente en {{appName}} está lista para descargarla",
"create_your_first_form": "Crea tu primer formulario", "create_your_first_form": "Crea tu primer formulario",
"create_your_first_form_description": "Con los formularios de orientación puedes hacer preguntas calificadoras y encaminarte hacia la persona o tipo de evento correctos.", "create_your_first_form_description": "Con los formularios de orientación puedes hacer preguntas calificadoras y encaminarte hacia la persona o tipo de evento correctos.",
"create_your_first_webhook": "Crea tu primer Webhook", "create_your_first_webhook": "Crea tu primer Webhook",
@@ -1265,7 +1335,9 @@
"event_one": "evento", "event_one": "evento",
"event_other": "eventos", "event_other": "eventos",
"profile_team_description": "Administra los ajustes para el perfil de tu equipo", "profile_team_description": "Administra los ajustes para el perfil de tu equipo",
"profile_org_description": "Administre la configuración para el perfil de su organización",
"members_team_description": "Usuarios que están en el grupo", "members_team_description": "Usuarios que están en el grupo",
"organization_description": "Gestione los administradores y miembros de su organización",
"team_url": "URL del equipo", "team_url": "URL del equipo",
"team_members": "Miembros del equipo", "team_members": "Miembros del equipo",
"more": "Más", "more": "Más",
@@ -1306,6 +1378,7 @@
"routing_forms_send_email_owner": "Enviar correo electrónico al propietario", "routing_forms_send_email_owner": "Enviar correo electrónico al propietario",
"routing_forms_send_email_owner_description": "Mande un correo electrónico al propietario cuando se envía el formulario", "routing_forms_send_email_owner_description": "Mande un correo electrónico al propietario cuando se envía el formulario",
"add_new_form": "Añadir formulario nuevo", "add_new_form": "Añadir formulario nuevo",
"add_new_team_form": "Añada un nuevo formulario a su equipo",
"create_your_first_route": "Cree su primera ruta", "create_your_first_route": "Cree su primera ruta",
"route_to_the_right_person": "Ruta a la persona adecuada en función de las respuestas a su formulario", "route_to_the_right_person": "Ruta a la persona adecuada en función de las respuestas a su formulario",
"form_description": "Crea tu formulario para dirigirlo a un agente de reservas", "form_description": "Crea tu formulario para dirigirlo a un agente de reservas",
@@ -1391,6 +1464,7 @@
"new_event_type_availability": "Disponibilidad para {{eventTypeTitle}}", "new_event_type_availability": "Disponibilidad para {{eventTypeTitle}}",
"error_editing_availability": "Error al editar la disponibilidad", "error_editing_availability": "Error al editar la disponibilidad",
"dont_have_permission": "No tiene permiso para acceder a este recurso.", "dont_have_permission": "No tiene permiso para acceder a este recurso.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Pega los metadatos SAML de tu Proveedor de Identidad aquí", "saml_configuration_placeholder": "Pega los metadatos SAML de tu Proveedor de Identidad aquí",
"saml_email_required": "Por favor, introduce un correo electrónico para que podamos encontrar tu Proveedor de Identidad SAML", "saml_email_required": "Por favor, introduce un correo electrónico para que podamos encontrar tu Proveedor de Identidad SAML",
"saml_sp_title": "Detalles del proveedor de servicios", "saml_sp_title": "Detalles del proveedor de servicios",
@@ -1409,15 +1483,19 @@
"yearly": "Anual", "yearly": "Anual",
"checkout": "Proceder al pago", "checkout": "Proceder al pago",
"your_team_disbanded_successfully": "Su equipo se ha disuelto con éxito", "your_team_disbanded_successfully": "Su equipo se ha disuelto con éxito",
"your_org_disbanded_successfully": "Su organización se ha disuelto con éxito",
"error_creating_team": "Error al crear el equipo", "error_creating_team": "Error al crear el equipo",
"you": "Usted", "you": "Usted",
"resend_email": "Reenviar correo electrónico",
"member_already_invited": "El miembro ya se ha invitado", "member_already_invited": "El miembro ya se ha invitado",
"enter_email_or_username": "Introduzca un correo electrónico o nombre de usuario", "enter_email_or_username": "Introduzca un correo electrónico o nombre de usuario",
"team_name_taken": "Este nombre ya está en uso", "team_name_taken": "Este nombre ya está en uso",
"must_enter_team_name": "Debe introducir un nombre de equipo", "must_enter_team_name": "Debe introducir un nombre de equipo",
"team_url_required": "Debe introducir una URL del equipo", "team_url_required": "Debe introducir una URL del equipo",
"url_taken": "Esta URL ya está en uso", "url_taken": "Esta URL ya está en uso",
"problem_registering_domain": "Hubo un problema con el registro del subdominio, intente nuevamente o comuníquese con un administrador",
"team_publish": "Publicar equipo", "team_publish": "Publicar equipo",
"number_text_notifications": "Número de teléfono (Notificaciones de texto)",
"attendee_email_variable": "Correo electrónico del asistente", "attendee_email_variable": "Correo electrónico del asistente",
"attendee_email_info": "El correo electrónico de la persona que reserva", "attendee_email_info": "El correo electrónico de la persona que reserva",
"kbar_search_placeholder": "Escriba un comando o búsqueda...", "kbar_search_placeholder": "Escriba un comando o búsqueda...",
@@ -1440,6 +1518,8 @@
"find_the_best_person": "Encuentre a la mejor persona disponible y haga una rotación en su equipo.", "find_the_best_person": "Encuentre a la mejor persona disponible y haga una rotación en su equipo.",
"fixed_round_robin": "Rotación fija por turnos", "fixed_round_robin": "Rotación fija por turnos",
"add_one_fixed_attendee": "Agregue un asistente fijo y realice rotación por turnos a través de un número de asistentes.", "add_one_fixed_attendee": "Agregue un asistente fijo y realice rotación por turnos a través de un número de asistentes.",
"calcom_is_better_with_team": "{{appName}} funciona mejor con equipos",
"the_calcom_team": "El equipo de {{companyName}}",
"add_your_team_members": "Añada los miembros de su equipo a sus tipos de eventos. Utilice la programación colectiva para incluir a todos o encuentre a la persona más adecuada con programación de rotación por turnos.", "add_your_team_members": "Añada los miembros de su equipo a sus tipos de eventos. Utilice la programación colectiva para incluir a todos o encuentre a la persona más adecuada con programación de rotación por turnos.",
"booking_limit_reached": "Se ha alcanzado el límite de reserva para este tipo de evento", "booking_limit_reached": "Se ha alcanzado el límite de reserva para este tipo de evento",
"duration_limit_reached": "Se ha alcanzado el límite de duración para este tipo de evento", "duration_limit_reached": "Se ha alcanzado el límite de duración para este tipo de evento",
@@ -1458,6 +1538,7 @@
"navigate_installed_apps": "Ir a las aplicaciones instaladas", "navigate_installed_apps": "Ir a las aplicaciones instaladas",
"disabled_calendar": "Si tiene otro calendario instalado, las nuevas reservas se añadirán a él. De lo contrario, conecte un nuevo calendario para que no se pierda ninguna reserva nueva.", "disabled_calendar": "Si tiene otro calendario instalado, las nuevas reservas se añadirán a él. De lo contrario, conecte un nuevo calendario para que no se pierda ninguna reserva nueva.",
"enable_apps": "Activar aplicaciones", "enable_apps": "Activar aplicaciones",
"enable_apps_description": "Habilite las aplicaciones que los usuarios pueden integrar con {{appName}}",
"purchase_license": "Compre una licencia", "purchase_license": "Compre una licencia",
"already_have_key": "Ya tengo una clave:", "already_have_key": "Ya tengo una clave:",
"already_have_key_suggestion": "Copie aquí su variable de entorno CALCOM_LICENSE_KEY existente.", "already_have_key_suggestion": "Copie aquí su variable de entorno CALCOM_LICENSE_KEY existente.",
@@ -1471,6 +1552,9 @@
"no_available_apps": "No hay aplicaciones disponibles", "no_available_apps": "No hay aplicaciones disponibles",
"no_available_apps_description": "Verifique que haya aplicaciones en su implementación en 'packages/app-store'", "no_available_apps_description": "Verifique que haya aplicaciones en su implementación en 'packages/app-store'",
"no_apps": "No hay aplicaciones activadas en esta instancia de Cal", "no_apps": "No hay aplicaciones activadas en esta instancia de Cal",
"no_apps_configured": "Aún no se ha configurado ninguna aplicación",
"enable_in_settings": "Puede activar aplicaciones en la configuración",
"please_contact_admin": "Póngase en contacto con su administrador",
"apps_settings": "Configuración de aplicaciones", "apps_settings": "Configuración de aplicaciones",
"fill_this_field": "Complete este campo", "fill_this_field": "Complete este campo",
"options": "Opciones", "options": "Opciones",
@@ -1574,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "¿Está seguro de que desea eliminar la configuración de {{connectionType}}? Los miembros de su equipo que utilicen el inicio de sesión {{connectionType}} ya no podrán acceder a Cal.com.", "delete_sso_configuration_confirmation_description": "¿Está seguro de que desea eliminar la configuración de {{connectionType}}? Los miembros de su equipo que utilicen el inicio de sesión {{connectionType}} ya no podrán acceder a Cal.com.",
"organizer_timezone": "Zona horaria del organizador", "organizer_timezone": "Zona horaria del organizador",
"email_user_cta": "Ver la invitación", "email_user_cta": "Ver la invitación",
"email_no_user_invite_heading": "Lo invitaron a unirse a {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} lo invitó a unirse a su equipo en {{appName}}. {{appName}} es el programador de eventos que les permite a usted y a su equipo programar reuniones sin necesidad de enviar correos electrónicos.", "email_no_user_invite_subheading": "{{invitedBy}} lo invitó a unirse a su equipo en {{appName}}. {{appName}} es el programador de eventos que les permite a usted y a su equipo programar reuniones sin necesidad de enviar correos electrónicos.",
"email_user_invite_subheading": "{{invitedBy}} lo ha invitado a unirse a su {{entity}} \"{{teamName}}\" en {{appName}}. {{appName}} es el planificador de eventos que le permite a usted y a su {{entity}} programar reuniones sin correos electrónicos de ida y vuelta.",
"email_no_user_invite_steps_intro": "Lo guiaremos a través de unos pocos pasos y disfrutará de una programación sin estrés con su {{entity}} en muy poco tiempo.",
"email_no_user_step_one": "Elija su nombre de usuario", "email_no_user_step_one": "Elija su nombre de usuario",
"email_no_user_step_two": "Conecte su cuenta de calendario", "email_no_user_step_two": "Conecte su cuenta de calendario",
"email_no_user_step_three": "Establezca su disponibilidad", "email_no_user_step_three": "Establezca su disponibilidad",
@@ -1585,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "No hay flujos de trabajo", "no_workflows": "No hay flujos de trabajo",
"change_filter": "Cambie el filtro para ver sus flujos de trabajo personales y de equipo.", "change_filter": "Cambie el filtro para ver sus flujos de trabajo personales y de equipo.",
"change_filter_common": "Cambie el filtro para ver los resultados.",
"no_results_for_filter": "No hay resultados para el filtro",
"recommended_next_steps": "Siguientes pasos recomendados", "recommended_next_steps": "Siguientes pasos recomendados",
"create_a_managed_event": "Crear un tipo de evento administrado", "create_a_managed_event": "Crear un tipo de evento administrado",
"meetings_are_better_with_the_right": "Las reuniones son mejores si están los miembros adecuados del equipo. Invítelos ahora.", "meetings_are_better_with_the_right": "Las reuniones son mejores si están los miembros adecuados del equipo. Invítelos ahora.",
@@ -1595,7 +1684,9 @@
"no_longer_attending": "Ya no asistirá a este evento", "no_longer_attending": "Ya no asistirá a este evento",
"attendee_no_longer_attending_subject": "Un asistente ya no asistirá a {{title}} a las {{date}}", "attendee_no_longer_attending_subject": "Un asistente ya no asistirá a {{title}} a las {{date}}",
"attendee_no_longer_attending": "Un asistente ya no asistirá a su evento", "attendee_no_longer_attending": "Un asistente ya no asistirá a su evento",
"attendee_no_longer_attending_subtitle": "{{name}} ha cancelado. Esto significa que está disponible una plaza para esta franja horaria",
"create_event_on": "Crear evento en", "create_event_on": "Crear evento en",
"create_routing_form_on": "Crear formulario de enrutamiento el",
"default_app_link_title": "Establecer un enlace de aplicación predeterminado", "default_app_link_title": "Establecer un enlace de aplicación predeterminado",
"default_app_link_description": "Establecer un enlace de aplicación predeterminado permite que todos los tipos de eventos recién creados utilicen el enlace de aplicación que establezca.", "default_app_link_description": "Establecer un enlace de aplicación predeterminado permite que todos los tipos de eventos recién creados utilicen el enlace de aplicación que establezca.",
"organizer_default_conferencing_app": "Aplicación por defecto del organizador", "organizer_default_conferencing_app": "Aplicación por defecto del organizador",
@@ -1605,6 +1696,7 @@
"booking_questions_title": "Preguntas sobre la reserva", "booking_questions_title": "Preguntas sobre la reserva",
"booking_questions_description": "Personalice las preguntas que se hacen en la página de reservas", "booking_questions_description": "Personalice las preguntas que se hacen en la página de reservas",
"add_a_booking_question": "Agregar una pregunta", "add_a_booking_question": "Agregar una pregunta",
"identifier": "Identificador",
"duplicate_email": "El correo electrónico está duplicado", "duplicate_email": "El correo electrónico está duplicado",
"booking_with_payment_cancelled": "Ya no es posible pagar por este evento", "booking_with_payment_cancelled": "Ya no es posible pagar por este evento",
"booking_with_payment_cancelled_already_paid": "Un reembolso por el pago de esta reserva está en camino.", "booking_with_payment_cancelled_already_paid": "Un reembolso por el pago de esta reserva está en camino.",
@@ -1615,6 +1707,7 @@
"show_on_booking_page": "Mostrar en la página de reserva", "show_on_booking_page": "Mostrar en la página de reserva",
"get_started_zapier_templates": "Comience con las plantillas de Zapier", "get_started_zapier_templates": "Comience con las plantillas de Zapier",
"team_is_unpublished": "{{team}} no está publicado", "team_is_unpublished": "{{team}} no está publicado",
"team_is_unpublished_description": "Este enlace de {{entity}} no está disponible actualmente. Póngase en contacto con el propietario de {{entity}} o pídale que lo publique.",
"team_member": "Miembro del equipo", "team_member": "Miembro del equipo",
"a_routing_form": "Un formulario de enrutamiento", "a_routing_form": "Un formulario de enrutamiento",
"form_description_placeholder": "Descripción del formulario", "form_description_placeholder": "Descripción del formulario",
@@ -1644,13 +1737,16 @@
"spot_popular_event_types": "Detectar tipos de eventos populares", "spot_popular_event_types": "Detectar tipos de eventos populares",
"spot_popular_event_types_description": "Consulte cuál de sus tipos de eventos están recibiendo más clics y reservas", "spot_popular_event_types_description": "Consulte cuál de sus tipos de eventos están recibiendo más clics y reservas",
"no_responses_yet": "Aún no hay respuestas", "no_responses_yet": "Aún no hay respuestas",
"no_routes_defined": "No hay rutas definidas",
"this_will_be_the_placeholder": "Este será el marcador de posición", "this_will_be_the_placeholder": "Este será el marcador de posición",
"error_booking_event": "Ocurrió un error al reservar el evento, actualice la página e intente nuevamente",
"timeslot_missing_title": "No hay intervalo de tiempo seleccionado", "timeslot_missing_title": "No hay intervalo de tiempo seleccionado",
"timeslot_missing_description": "Seleccione un intervalo de tiempo para reservar el evento.", "timeslot_missing_description": "Seleccione un intervalo de tiempo para reservar el evento.",
"timeslot_missing_cta": "Seleccionar intervalo de tiempo", "timeslot_missing_cta": "Seleccionar intervalo de tiempo",
"switch_monthly": "Cambiar a la vista mensual", "switch_monthly": "Cambiar a la vista mensual",
"switch_weekly": "Cambiar a la vista semanal", "switch_weekly": "Cambiar a la vista semanal",
"switch_multiday": "Cambiar a la vista diaria", "switch_multiday": "Cambiar a la vista diaria",
"switch_columnview": "Cambiar a la vista de columna",
"num_locations": "{{num}} opciones de ubicación", "num_locations": "{{num}} opciones de ubicación",
"select_on_next_step": "Seleccionar en el siguiente paso", "select_on_next_step": "Seleccionar en el siguiente paso",
"this_meeting_has_not_started_yet": "Esta reunión aún no ha comenzado", "this_meeting_has_not_started_yet": "Esta reunión aún no ha comenzado",
@@ -1689,6 +1785,7 @@
"managed_event_dialog_title_one": "La url /{{slug}} ya existe para {{count}} miembro. ¿Desea reemplazarla?", "managed_event_dialog_title_one": "La url /{{slug}} ya existe para {{count}} miembro. ¿Desea reemplazarla?",
"managed_event_dialog_title_other": "La url /{{slug}} ya existe para {{count}} miembros. ¿Desea reemplazarla?", "managed_event_dialog_title_other": "La url /{{slug}} ya existe para {{count}} miembros. ¿Desea reemplazarla?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> ya usa la url <strong>/{{slug}}</strong>.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> ya usa la url <strong>/{{slug}}</strong>.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> ya usan la url <strong>/{{slug}}</strong>.",
"managed_event_dialog_clarification": "Si elige reemplazarlo, se lo notificaremos. Regrese y elimínelos si no desea sobrescribirlo.", "managed_event_dialog_clarification": "Si elige reemplazarlo, se lo notificaremos. Regrese y elimínelos si no desea sobrescribirlo.",
"review_event_type": "Revisar tipo de evento", "review_event_type": "Revisar tipo de evento",
"looking_for_more_analytics": "¿Busca más datos de análisis?", "looking_for_more_analytics": "¿Busca más datos de análisis?",
@@ -1704,12 +1801,14 @@
"least_booked_members": "Miembros con menos reservas", "least_booked_members": "Miembros con menos reservas",
"events_created": "Eventos creados", "events_created": "Eventos creados",
"events_completed": "Eventos completados", "events_completed": "Eventos completados",
"events_cancelled": "Eventos cancelados",
"events_rescheduled": "Eventos reprogramados", "events_rescheduled": "Eventos reprogramados",
"from_last_period": "desde el último período", "from_last_period": "desde el último período",
"from_to_date_period": "Desde: {{startDate}} Hasta: {{endDate}}", "from_to_date_period": "Desde: {{startDate}} Hasta: {{endDate}}",
"redirect_url_warning": "Agregar una redirección deshabilitará la página de éxito. Asegúrese de mencionar \"Reserva confirmada\" en su página de éxito personalizada.", "redirect_url_warning": "Agregar una redirección deshabilitará la página de éxito. Asegúrese de mencionar \"Reserva confirmada\" en su página de éxito personalizada.",
"event_trends": "Tendencias del evento", "event_trends": "Tendencias del evento",
"clear_filters": "Eliminar filtros", "clear_filters": "Eliminar filtros",
"clear": "Borrar",
"hold": "Retener", "hold": "Retener",
"on_booking_option": "Cobrar el pago durante la reserva", "on_booking_option": "Cobrar el pago durante la reserva",
"hold_option": "Cobrar comisión por no presentarse", "hold_option": "Cobrar comisión por no presentarse",
@@ -1736,6 +1835,18 @@
"complete_your_booking": "Complete su reserva", "complete_your_booking": "Complete su reserva",
"complete_your_booking_subject": "Complete su reserva: {{title}} el {{date}}", "complete_your_booking_subject": "Complete su reserva: {{title}} el {{date}}",
"confirm_your_details": "Confirme sus datos", "confirm_your_details": "Confirme sus datos",
"copy_invite_link": "Copiar enlace de invitación",
"edit_invite_link": "Editar ajustes de enlace",
"invite_link_copied": "Enlace de invitación copiado",
"invite_link_deleted": "Enlace de invitación eliminado",
"invite_link_updated": "Configuración de enlace de invitación guardada",
"link_expires_after": "Enlaces establecidos para expirar después de...",
"one_day": "1 día",
"seven_days": "7 días",
"thirty_days": "30 días",
"three_months": "3 meses",
"one_year": "1 año",
"team_invite_received": "Lo han invitado a unirse a {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Está a punto de cobrarle {{amount, currency}} al asistente. ¿Está seguro de que desea continuar?", "charge_card_dialog_body": "Está a punto de cobrarle {{amount, currency}} al asistente. ¿Está seguro de que desea continuar?",
"charge_attendee": "Cobrar al asistente {{amount, currency}}", "charge_attendee": "Cobrar al asistente {{amount, currency}}",
@@ -1744,6 +1855,7 @@
"email_invite_team_bulk": "Se han invitado {{userCount}} usuarios", "email_invite_team_bulk": "Se han invitado {{userCount}} usuarios",
"error_collecting_card": "Error al cargar la tarjeta", "error_collecting_card": "Error al cargar la tarjeta",
"image_size_limit_exceed": "La imagen cargada no debe exceder el límite de tamaño de 5 Mb", "image_size_limit_exceed": "La imagen cargada no debe exceder el límite de tamaño de 5 Mb",
"unauthorized_workflow_error_message": "{{errorCode}}: No está autorizado para habilitar o deshabilitar este flujo de trabajo",
"inline_embed": "Incrustar en línea", "inline_embed": "Incrustar en línea",
"load_inline_content": "Carga su tipo de evento directamente en línea con otro contenido de su sitio web.", "load_inline_content": "Carga su tipo de evento directamente en línea con otro contenido de su sitio web.",
"floating_pop_up_button": "Botón emergente flotante", "floating_pop_up_button": "Botón emergente flotante",
@@ -1763,6 +1875,69 @@
"connect_google_workspace": "Conectar Google Workspace", "connect_google_workspace": "Conectar Google Workspace",
"google_workspace_admin_tooltip": "Debe ser administrador para usar esta función", "google_workspace_admin_tooltip": "Debe ser administrador para usar esta función",
"first_event_type_webhook_description": "Cree su primer webhook para este tipo de evento", "first_event_type_webhook_description": "Cree su primer webhook para este tipo de evento",
"install_app_on": "Instalar aplicación en",
"create_for": "Crear para", "create_for": "Crear para",
"insights_all_org_filter": "Todas las aplicaciones" "setup_organization": "Configurar una organización",
"organization_banner_description": "Cree entornos en los que sus equipos puedan crear aplicaciones, flujos de trabajo y tipos de eventos compartidos con programación por turnos y colectiva.",
"organization_banner_title": "Gestione organizaciones con varios equipos",
"set_up_your_organization": "Configure su organización",
"organizations_description": "Las organizaciones son entornos compartidos donde los equipos pueden crear tipos de eventos, aplicaciones, flujos de trabajo compartidos y más.",
"must_enter_organization_name": "Debe introducir el nombre de una organización",
"must_enter_organization_admin_email": "Debe introducir la dirección de correo electrónico de su organización",
"admin_email": "Dirección de correo electrónico de su organización",
"admin_username": "Nombre de usuario del administrador",
"organization_name": "Nombre de la organización",
"organization_url": "URL de la organización",
"organization_verify_header": "Verifique el correo electrónico de su organización",
"organization_verify_email_body": "Utilice el código a continuación para verificar su dirección de correo electrónico para seguir configurando su organización.",
"additional_url_parameters": "Parámetros adicionales de URL",
"about_your_organization": "Acerca de su organización",
"about_your_organization_description": "Las organizaciones son entornos compartidos donde puede crear varios equipos con miembros, tipos de eventos, aplicaciones, flujos de trabajo compartidos y más.",
"create_your_teams": "Cree sus equipos",
"create_your_teams_description": "Comiencen a programar juntos agregando miembros de su equipo a su organización",
"invite_organization_admins": "Invite a los administradores de su organización",
"invite_organization_admins_description": "Estos administradores tendrán acceso a todos los equipos de su organización. Puede agregar administradores y miembros del equipo más tarde.",
"set_a_password": "Establezca una contraseña",
"set_a_password_description": "Esto creará una nueva cuenta de usuario con el correo electrónico de su organización y esta contraseña.",
"organization_logo": "Logo de la organización",
"organization_about_description": "Algunas frases sobre su organización. Esto aparecerá en la página de perfil público de su organización.",
"ill_do_this_later": "Lo haré más tarde",
"verify_your_email": "Verifique su correo electrónico",
"enter_digit_code": "Ingrese el código de 6 dígitos que enviamos a {{email}}",
"verify_email_organization": "Verifique su correo electrónico para crear una organización",
"code_provided_invalid": "El código proporcionado no es válido, inténtelo de nuevo",
"email_already_used": "El correo electrónico ya se está utilizando",
"organization_admin_invited_heading": "Lo han invitado a unirse a {{orgName}}",
"organization_admin_invited_body": "Únase a su equipo en {{orgName}} y comience a concentrarse en las reuniones, no en hacer reuniones.",
"duplicated_slugs_warning": "No se pudieron crear los siguientes equipos debido a slugs duplicados: {{slugs}}",
"team_names_empty": "Los nombres de equipo no pueden estar vacíos",
"team_names_repeated": "Los nombres de equipo no se pueden repetir",
"user_belongs_organization": "El usuario pertenece a una organización",
"org_no_teams_yet": "Esta organización aún no tiene equipos",
"org_no_teams_yet_description": "Si usted es un administrador, asegúrese de crear equipos para que se muestren aquí.",
"set_up": "Configurar",
"set_up_your_profile": "Configure su perfil",
"set_up_your_profile_description": "Informe a las personas quién es usted dentro de {{orgName}} cuándo interactúan con su enlace público.",
"my_profile": "Mi perfil",
"my_settings": "Mi configuración",
"crm": "CRM",
"messaging": "Mensajería",
"sender_id_info": "Nombre o número que se muestra como el remitente de un SMS (algunos países no permiten ID de remitente alfanumérico)",
"org_admins_can_create_new_teams": "Sólo el administrador de su organización puede crear nuevos equipos",
"google_new_spam_policy": "La nueva política de spam de Google podría evitar que reciba notificaciones por correo electrónico y calendario sobre esta reserva.",
"resolve": "Resolver",
"no_organization_slug": "Hubo un error al crear equipos para esta organización. Falta el slug de URL.",
"org_name": "Nombre de la organización",
"org_url": "URL de la organización",
"copy_link_org": "Copiar enlace a la organización",
"404_the_org": "La organización",
"404_the_team": "El equipo",
"404_claim_entity_org": "Reclame su subdominio para su organización",
"404_claim_entity_team": "Reclama este equipo y empiece a gestionar los horarios de forma colectiva",
"insights_all_org_filter": "Todas las aplicaciones",
"insights_team_filter": "Equipo: {{teamName}}",
"insights_user_filter": "Usuario: {{userName}}",
"insights_subtitle": "Mire información de insights en todos sus eventos",
"custom_plan": "Plan personalizado",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agregue sus nuevas cadenas arriba ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -244,6 +244,8 @@
"all": "Tous", "all": "Tous",
"yours": "Votre compte", "yours": "Votre compte",
"available_apps": "Applications disponibles", "available_apps": "Applications disponibles",
"available_apps_lower_case": "Applications disponibles",
"available_apps_desc": "Aucune application installée. Consultez les applications populaires ci-dessous et découvrez-en plus dans notre <1>App Store</1>.",
"check_email_reset_password": "Vérifiez vos e-mails. Nous vous avons envoyé un lien pour réinitialiser votre mot de passe.", "check_email_reset_password": "Vérifiez vos e-mails. Nous vous avons envoyé un lien pour réinitialiser votre mot de passe.",
"finish": "Terminer", "finish": "Terminer",
"organization_general_description": "Gérez les paramètres de langue et de fuseau horaire de votre équipe.", "organization_general_description": "Gérez les paramètres de langue et de fuseau horaire de votre équipe.",
@@ -407,6 +409,7 @@
"booking_requested": "Réservation demandée", "booking_requested": "Réservation demandée",
"meeting_ended": "Rendez-vous terminé", "meeting_ended": "Rendez-vous terminé",
"form_submitted": "Formulaire envoyé", "form_submitted": "Formulaire envoyé",
"booking_paid": "Réservation payée",
"event_triggers": "Déclencheurs d'événement", "event_triggers": "Déclencheurs d'événement",
"subscriber_url": "Lien de l'abonné", "subscriber_url": "Lien de l'abonné",
"create_new_webhook": "Créez un nouveau webhook", "create_new_webhook": "Créez un nouveau webhook",
@@ -1865,6 +1868,9 @@
"open_dialog_with_element_click": "Ouvre votre boîte de dialogue Cal lorsque quelqu'un clique sur un élément.", "open_dialog_with_element_click": "Ouvre votre boîte de dialogue Cal lorsque quelqu'un clique sur un élément.",
"need_help_embedding": "Besoin d'aide ? Consultez nos guides pour intégrer Cal sur Wix, Squarespace ou WordPress, consultez nos questions fréquentes ou explorez les options d'intégration avancées.", "need_help_embedding": "Besoin d'aide ? Consultez nos guides pour intégrer Cal sur Wix, Squarespace ou WordPress, consultez nos questions fréquentes ou explorez les options d'intégration avancées.",
"book_my_cal": "Prendre rendez-vous", "book_my_cal": "Prendre rendez-vous",
"first_name": "Prénom",
"last_name": "Nom",
"first_last_name": "Prénom, Nom",
"invite_as": "Inviter en tant que", "invite_as": "Inviter en tant que",
"form_updated_successfully": "Formulaire mis à jour avec succès.", "form_updated_successfully": "Formulaire mis à jour avec succès.",
"disable_attendees_confirmation_emails": "Désactiver les e-mails de confirmation par défaut pour les participants", "disable_attendees_confirmation_emails": "Désactiver les e-mails de confirmation par défaut pour les participants",
@@ -1939,6 +1945,7 @@
"insights_team_filter": "Équipe : {{teamName}}", "insights_team_filter": "Équipe : {{teamName}}",
"insights_user_filter": "Utilisateur : {{userName}}", "insights_user_filter": "Utilisateur : {{userName}}",
"insights_subtitle": "Visualisez les statistiques de réservation à travers vos événements", "insights_subtitle": "Visualisez les statistiques de réservation à travers vos événements",
"location_options": "{{locationCount}} options de lieu",
"custom_plan": "Plan personnalisé", "custom_plan": "Plan personnalisé",
"org_team_names_example": "p. ex. Équipe marketing", "org_team_names_example": "p. ex. Équipe marketing",
"org_team_names_example_1": "p. ex. Équipe marketing", "org_team_names_example_1": "p. ex. Équipe marketing",
@@ -1946,5 +1953,6 @@
"org_team_names_example_3": "p. ex. Équipe de design", "org_team_names_example_3": "p. ex. Équipe de design",
"org_team_names_example_4": "p. ex. Équipe d'ingénierie", "org_team_names_example_4": "p. ex. Équipe d'ingénierie",
"org_team_names_example_5": "p. ex. Équipe d'analyse de données", "org_team_names_example_5": "p. ex. Équipe d'analyse de données",
"org_max_team_warnings": "Vous pourrez ajouter plus d'équipes plus tard.",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -1658,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "Eliminare la configurazione {{connectionType}}? I membri del tuo team che utilizzano l'accesso {{connectionType}} non saranno più in grado di accedere a Cal.com.", "delete_sso_configuration_confirmation_description": "Eliminare la configurazione {{connectionType}}? I membri del tuo team che utilizzano l'accesso {{connectionType}} non saranno più in grado di accedere a Cal.com.",
"organizer_timezone": "Fuso orario organizzatore", "organizer_timezone": "Fuso orario organizzatore",
"email_user_cta": "Visualizza invito", "email_user_cta": "Visualizza invito",
"email_no_user_invite_heading": "Hai ricevuto un invito a unirti a {{entity}} di {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.", "email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
"email_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti a {{entity}} `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette a te e al tuo {{entity}} di pianificare le riunioni senza scambiare decine di e-mail.",
"email_no_user_invite_steps_intro": "Ti assisteremo nei passaggi iniziali in modo che tu possa pianificare eventi per il tuo {{entity}} senza stress e in pochissimo tempo.",
"email_no_user_step_one": "Scegli il tuo nome utente", "email_no_user_step_one": "Scegli il tuo nome utente",
"email_no_user_step_two": "Collega il tuo account di calendario", "email_no_user_step_two": "Collega il tuo account di calendario",
"email_no_user_step_three": "Imposta la tua disponibilità", "email_no_user_step_three": "Imposta la tua disponibilità",
@@ -1669,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "Nessun flusso di lavoro", "no_workflows": "Nessun flusso di lavoro",
"change_filter": "Modifica il filtro per vedere i flussi di lavoro personali e di squadra.", "change_filter": "Modifica il filtro per vedere i flussi di lavoro personali e di squadra.",
"change_filter_common": "Cambia i criteri di filtro per vedere i risultati.",
"no_results_for_filter": "Nessun risultato per il filtro",
"recommended_next_steps": "Passaggi successivi consigliati", "recommended_next_steps": "Passaggi successivi consigliati",
"create_a_managed_event": "Crea un tipo di evento gestito", "create_a_managed_event": "Crea un tipo di evento gestito",
"meetings_are_better_with_the_right": "Le riunioni sono efficaci quando sono presenti le persone giuste. Invitale adesso.", "meetings_are_better_with_the_right": "Le riunioni sono efficaci quando sono presenti le persone giuste. Invitale adesso.",
@@ -1679,7 +1684,9 @@
"no_longer_attending": "Non partecipi più a questo evento", "no_longer_attending": "Non partecipi più a questo evento",
"attendee_no_longer_attending_subject": "Un partecipante non partecipa più a {{title}} con il seguente orario {{date}}", "attendee_no_longer_attending_subject": "Un partecipante non partecipa più a {{title}} con il seguente orario {{date}}",
"attendee_no_longer_attending": "Un partecipante non partecipa più al tuo evento", "attendee_no_longer_attending": "Un partecipante non partecipa più al tuo evento",
"attendee_no_longer_attending_subtitle": "{{name}} ha disdetto. Di conseguenza, si è liberato un posto in questa fascia oraria",
"create_event_on": "Crea evento in", "create_event_on": "Crea evento in",
"create_routing_form_on": "Crea modulo di instradamento su",
"default_app_link_title": "Imposta il link dell'app predefinita", "default_app_link_title": "Imposta il link dell'app predefinita",
"default_app_link_description": "L'impostazione di un link dell'app predefinita permette a tutti i nuovi tipi di eventi di usare il link dell'app impostato.", "default_app_link_description": "L'impostazione di un link dell'app predefinita permette a tutti i nuovi tipi di eventi di usare il link dell'app impostato.",
"organizer_default_conferencing_app": "Applicazione predefinita dell'organizzatore", "organizer_default_conferencing_app": "Applicazione predefinita dell'organizzatore",
@@ -1700,6 +1707,7 @@
"show_on_booking_page": "Mostra nella pagina di prenotazione", "show_on_booking_page": "Mostra nella pagina di prenotazione",
"get_started_zapier_templates": "Inizia con i modelli Zapier", "get_started_zapier_templates": "Inizia con i modelli Zapier",
"team_is_unpublished": "{{team}} non è pubblicato", "team_is_unpublished": "{{team}} non è pubblicato",
"team_is_unpublished_description": "Questo link di {{entity}} non è attualmente disponibile. Contatta il proprietario di {{entity}} o chiedigli di pubblicarlo.",
"team_member": "Membro del team", "team_member": "Membro del team",
"a_routing_form": "Un modulo di instradamento", "a_routing_form": "Un modulo di instradamento",
"form_description_placeholder": "Descrizione modulo", "form_description_placeholder": "Descrizione modulo",
@@ -1731,6 +1739,7 @@
"no_responses_yet": "Per ora non ci sono risposte", "no_responses_yet": "Per ora non ci sono risposte",
"no_routes_defined": "Nessun percorso definito", "no_routes_defined": "Nessun percorso definito",
"this_will_be_the_placeholder": "Questo sarà il segnaposto", "this_will_be_the_placeholder": "Questo sarà il segnaposto",
"error_booking_event": "Si è verificato un errore durante la prenotazione dell'evento. Aggiorna la pagina e riprova",
"timeslot_missing_title": "Nessuna fascia oraria selezionata", "timeslot_missing_title": "Nessuna fascia oraria selezionata",
"timeslot_missing_description": "Seleziona una fascia oraria per prenotare l'evento.", "timeslot_missing_description": "Seleziona una fascia oraria per prenotare l'evento.",
"timeslot_missing_cta": "Seleziona fascia oraria", "timeslot_missing_cta": "Seleziona fascia oraria",
@@ -1776,6 +1785,7 @@
"managed_event_dialog_title_one": "L'URL /{{slug}} esiste già per {{count}} membro. Vuoi sostituirlo?", "managed_event_dialog_title_one": "L'URL /{{slug}} esiste già per {{count}} membro. Vuoi sostituirlo?",
"managed_event_dialog_title_other": "L'URL /{{slug}} esiste già per {{count}} membri. Vuoi sostituirlo?", "managed_event_dialog_title_other": "L'URL /{{slug}} esiste già per {{count}} membri. Vuoi sostituirlo?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> utilizza già l'URL <strong>/{{slug}}</strong>.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> utilizza già l'URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> utilizzano già l'URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_clarification": "Se decidi di sostituirlo, i membri ne saranno avvisati. Torna indietro e rimuovili se non desideri sovrascriverlo.", "managed_event_dialog_clarification": "Se decidi di sostituirlo, i membri ne saranno avvisati. Torna indietro e rimuovili se non desideri sovrascriverlo.",
"review_event_type": "Rivedi tipo di evento", "review_event_type": "Rivedi tipo di evento",
"looking_for_more_analytics": "Hai bisogno di più dati analitici?", "looking_for_more_analytics": "Hai bisogno di più dati analitici?",
@@ -1791,12 +1801,14 @@
"least_booked_members": "Membri meno prenotati", "least_booked_members": "Membri meno prenotati",
"events_created": "Eventi creati", "events_created": "Eventi creati",
"events_completed": "Eventi completati", "events_completed": "Eventi completati",
"events_cancelled": "Eventi cancellati",
"events_rescheduled": "Eventi riprogrammati", "events_rescheduled": "Eventi riprogrammati",
"from_last_period": "dal periodo precedente", "from_last_period": "dal periodo precedente",
"from_to_date_period": "Da: {{startDate}} A: {{endDate}}", "from_to_date_period": "Da: {{startDate}} A: {{endDate}}",
"redirect_url_warning": "Aggiungendo un reindirizzamento, viene disabilitata la pagina di conferma dell'esito. Assicurati che nella pagina di conferma dell'esito personalizzata compaia la dicitura \"Prenotazione confermata\".", "redirect_url_warning": "Aggiungendo un reindirizzamento, viene disabilitata la pagina di conferma dell'esito. Assicurati che nella pagina di conferma dell'esito personalizzata compaia la dicitura \"Prenotazione confermata\".",
"event_trends": "Tendenze eventi", "event_trends": "Tendenze eventi",
"clear_filters": "Cancella filtri", "clear_filters": "Cancella filtri",
"clear": "Cancella",
"hold": "Preautorizzazione", "hold": "Preautorizzazione",
"on_booking_option": "Raccogli pagamento alla prenotazione", "on_booking_option": "Raccogli pagamento alla prenotazione",
"hold_option": "Addebita penale per mancata presentazione", "hold_option": "Addebita penale per mancata presentazione",
@@ -1832,6 +1844,8 @@
"one_day": "1 giorno", "one_day": "1 giorno",
"seven_days": "7 giorni", "seven_days": "7 giorni",
"thirty_days": "30 giorni", "thirty_days": "30 giorni",
"three_months": "3 mesi",
"one_year": "1 anno",
"team_invite_received": "Hai ricevuto un invito a unirti al team {{teamName}}", "team_invite_received": "Hai ricevuto un invito a unirti al team {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Stai per addebitare {{amount, currency}} al partecipante. Confermi di voler proseguire?", "charge_card_dialog_body": "Stai per addebitare {{amount, currency}} al partecipante. Confermi di voler proseguire?",
@@ -1861,9 +1875,69 @@
"connect_google_workspace": "Collega Google Workspace", "connect_google_workspace": "Collega Google Workspace",
"google_workspace_admin_tooltip": "Per usare questa funzione è necessario essere amministratori di Workspace", "google_workspace_admin_tooltip": "Per usare questa funzione è necessario essere amministratori di Workspace",
"first_event_type_webhook_description": "Crea il primo webhook per questo tipo di evento", "first_event_type_webhook_description": "Crea il primo webhook per questo tipo di evento",
"install_app_on": "Installa l'app su",
"create_for": "Crea per", "create_for": "Crea per",
"setup_organization": "Imposta un'organizzazione",
"organization_banner_description": "Crea un ambiente dove i tuoi team potranno creare applicazioni condivise, flussi di lavoro e tipi di eventi con pianificazioni di gruppo e round robin.",
"organization_banner_title": "Gestisci organizzazioni con più team",
"set_up_your_organization": "Imposta la tua organizzazione",
"organizations_description": "Le organizzazioni sono ambienti condivisi dove i team possono creare tipi di eventi, applicazioni, flussi di lavoro condivisi e tanto altro.",
"must_enter_organization_name": "È necessario inserire un nome di organizzazione",
"must_enter_organization_admin_email": "È necessario inserire l'indirizzo e-mail dell'organizzazione",
"admin_email": "Indirizzo e-mail dell'organizzazione",
"admin_username": "Nome utente dell'amministratore",
"organization_name": "Nome dell'organizzazione",
"organization_url": "URL dell'organizzazione",
"organization_verify_header": "Verifica l'e-mail della tua organizzazione",
"organization_verify_email_body": "Usa il codice sottostante per verificare il tuo indirizzo e-mail e continuare a impostare l'organizzazione.",
"additional_url_parameters": "Parametri URL aggiuntivi", "additional_url_parameters": "Parametri URL aggiuntivi",
"about_your_organization": "Informazioni sulla tua organizzazione",
"about_your_organization_description": "Le organizzazioni sono ambienti condivisi dove è possibile creare più team con membri, tipi di eventi, applicazioni, flussi di lavoro condivisi e tanto altro.",
"create_your_teams": "Crea i tuoi team",
"create_your_teams_description": "Inizia la pianificazione condivisa aggiungendo i membri del tuo team alla tua organizzazione",
"invite_organization_admins": "Invita gli amministratori dell'organizzazione",
"invite_organization_admins_description": "Gli amministratori avranno l'accesso a tutti i team della tua organizzazione. Puoi aggiungere amministratori e membri dei team in un secondo tempo.",
"set_a_password": "Imposta una password",
"set_a_password_description": "Verrà creato un nuovo account utente con l'indirizzo e-mail della tua organizzazione e questa password.",
"organization_logo": "Logo dell'organizzazione",
"organization_about_description": "Qualche informazione sulla tua organizzazione. Le informazioni appariranno nella pagina di profilo dell'organizzazione.",
"ill_do_this_later": "Lo farò più tardi",
"verify_your_email": "Verifica l'e-mail",
"enter_digit_code": "Immetti il codice di 6 cifre che ti è stato inviato a {{email}}",
"verify_email_organization": "Verifica il tuo indirizzo email per creare un'organizzazione",
"code_provided_invalid": "Il codice immesso non è valido, riprova",
"email_already_used": "Indirizzo email già in uso",
"organization_admin_invited_heading": "Hai ricevuto un invito a unirti a {{orgName}}",
"organization_admin_invited_body": "Unisciti al tuo team su {{orgName}} per concentrarti sulle riunioni, non sulla loro pianificazione!",
"duplicated_slugs_warning": "Non è stato possibile creare i seguenti team a causa di slug duplicati: {{slugs}}",
"team_names_empty": "I nomi di team non possono essere vuoti",
"team_names_repeated": "I nomi di team non possono essere ripetuti",
"user_belongs_organization": "L'utente appartiene a un'organizzazione",
"org_no_teams_yet": "Questa organizzazione non ha ancora nessun team",
"org_no_teams_yet_description": "Se sei un amministratore, assicurati di creare dei team da mostrare qui.",
"set_up": "Imposta",
"set_up_your_profile": "Imposta il tuo profilo",
"set_up_your_profile_description": "Fai sapere agli utenti la tua posizione all'interno di {{orgName}} quando interagiscono con il tuo link pubblico.",
"my_profile": "Il mio profilo",
"my_settings": "Le mie impostazioni",
"crm": "CRM",
"messaging": "Messaggistica",
"sender_id_info": "Nome o numero mostrato come mittente di un SMS (alcuni paesi non consentono ID alfanumerici dei mittenti)", "sender_id_info": "Nome o numero mostrato come mittente di un SMS (alcuni paesi non consentono ID alfanumerici dei mittenti)",
"org_admins_can_create_new_teams": "Solo l'amministratore della tua organizzazione può creare nuovi team",
"google_new_spam_policy": "Le nuove norme sullo spam di Google potrebbero impedirti di ricevere email e notifiche di calendario in merito a questa prenotazione.",
"resolve": "Risolvi",
"no_organization_slug": "Si è verificato un errore durante la creazione di team per questa organizzazione. Slug di URL mancante.",
"org_name": "Nome dell'organizzazione",
"org_url": "URL dell'organizzazione",
"copy_link_org": "Copia link all'organizzazione",
"404_the_org": "L'organizzazione",
"404_the_team": "Il team",
"404_claim_entity_org": "Richiedi il sottodominio per la tua organizzazione",
"404_claim_entity_team": "Richiedi questo team e inizia a gestire le pianificazioni collettivamente",
"insights_all_org_filter": "Tutte le app", "insights_all_org_filter": "Tutte le app",
"insights_team_filter": "Team: {{teamName}}",
"insights_user_filter": "Utente: {{userName}}",
"insights_subtitle": "Visualizza le informazioni sulle prenotazioni per tutti i tuoi eventi",
"custom_plan": "Piano personalizzato",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑↑ Aggiungi qui le tue nuove stringhe al di sopra di questa riga ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑↑ Aggiungi qui le tue nuove stringhe al di sopra di questa riga ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑"
} }
+60 -1
View File
@@ -1880,5 +1880,64 @@
"setup_organization": "Organization をセットアップ", "setup_organization": "Organization をセットアップ",
"organization_banner_description": "チームがラウンドロビンスケジューリングや一括スケジューリングで、共有アプリ、ワークフロー、イベントの種類を作成できる環境を作成します。", "organization_banner_description": "チームがラウンドロビンスケジューリングや一括スケジューリングで、共有アプリ、ワークフロー、イベントの種類を作成できる環境を作成します。",
"organization_banner_title": "複数のチームを持つ組織を管理", "organization_banner_title": "複数のチームを持つ組織を管理",
"insights_all_org_filter": "すべて" "set_up_your_organization": "組織をセットアップ",
"organizations_description": "組織はチームが共有するイベントの種類、アプリ、ワークフローなどを作成できる共有環境です。",
"must_enter_organization_name": "組織の名前の入力は必須です",
"must_enter_organization_admin_email": "組織のメールアドレスの入力は必須です",
"admin_email": "組織のメールアドレス",
"admin_username": "管理者のユーザー名",
"organization_name": "組織の名前",
"organization_url": "Organization の URL",
"organization_verify_header": "組織のメールアドレスを確認してください",
"organization_verify_email_body": "組織のセットアップを続行するには、以下のコードを使ってメールアドレスを確認してください。",
"additional_url_parameters": "追加の URL パラメータ",
"about_your_organization": "あなたの組織について",
"about_your_organization_description": "組織は共有するメンバー、イベントの種類、アプリ、ワークフローなどを含む複数のチームを作成できる共有環境です。",
"create_your_teams": "チームを作成",
"create_your_teams_description": "組織にチームメンバーを追加して、共同のスケジューリングを開始します",
"invite_organization_admins": "組織の管理者を招待",
"invite_organization_admins_description": "これらの管理者は組織のすべてのチームにアクセスできます。チームの管理者とメンバーは後で追加できます。",
"set_a_password": "パスワードを設定",
"set_a_password_description": "これにより、組織のメールアドレスとこのパスワードを使って、新規ユーザーアカウントが作成されます。",
"organization_logo": "Organization のロゴ",
"organization_about_description": "あなたの組織についての簡単な説明文です。あなたの組織の公開 プロフィールページに表示されます。",
"ill_do_this_later": "これは後でする",
"verify_your_email": "メールを確認",
"enter_digit_code": "{{email}} に送信した6桁のコードを入力してください",
"verify_email_organization": "組織を作成するには、メールを確認してください",
"code_provided_invalid": "提供されたコードは有効ではありません。もう一度お試しください",
"email_already_used": "メールはすでに使用されています",
"organization_admin_invited_heading": "{{orgName}} に参加するよう招待されました",
"organization_admin_invited_body": "{{orgName}} のチームに参加して、これからはスケジューリングではなくミーティングに集中しましょう!",
"duplicated_slugs_warning": "次のチームはスラッグが重複しているため作成できませんでした:{{slugs}}",
"team_names_empty": "チーム名は空欄にできません",
"team_names_repeated": "チーム名を繰り返し使用することはできません",
"user_belongs_organization": "ユーザーは組織の一員です",
"org_no_teams_yet": "この組織にはまだチームがありません",
"org_no_teams_yet_description": "管理者である場合は、必ずここに表示されるチームを作成してください。",
"set_up": "設定",
"set_up_your_profile": "プロフィールを設定",
"set_up_your_profile_description": "あなたのことを {{orgName}} 内、そして公開リンクを見る人に知ってもらいます。",
"my_profile": "プロフィール",
"my_settings": "設定",
"crm": "CRM",
"messaging": "メッセージング",
"sender_id_info": "SMS の送信者として表示される名前または番号(国によっては英数字の送信者 ID を許可しない場合があります)",
"org_admins_can_create_new_teams": "組織の管理者のみが新規チームを作成できます",
"google_new_spam_policy": "Goggleのスパムに関する新しいポリシーにより、この予約についてのメールやカレンダー通知を受け取れなくなる可能性があります。",
"resolve": "解決する",
"no_organization_slug": "この組織のチームの作成中にエラーが発生しました。URL スラッグがありません。",
"org_name": "組織の名前",
"org_url": "組織の URL",
"copy_link_org": "組織へのリンクをコピー",
"404_the_org": "組織",
"404_the_team": "チーム",
"404_claim_entity_org": "組織のサブドメインを取得",
"404_claim_entity_team": "このチームを取得して、これからはスケジュールをまとめて管理しましょう",
"insights_all_org_filter": "すべて",
"insights_team_filter": "チーム:{{teamName}}",
"insights_user_filter": "ユーザー:{{userName}}",
"insights_subtitle": "イベント全体の予約 Insights を表示",
"custom_plan": "カスタムプラン",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ この上に新しい文字列を追加 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+189 -1
View File
@@ -13,11 +13,21 @@
"reset_password_subject": "{{appName}}: Instructies voor het opnieuw instellen van uw wachtwoord", "reset_password_subject": "{{appName}}: Instructies voor het opnieuw instellen van uw wachtwoord",
"verify_email_subject": "{{appName}}: Verifieer je account", "verify_email_subject": "{{appName}}: Verifieer je account",
"check_your_email": "Controleer je e-mail", "check_your_email": "Controleer je e-mail",
"verify_email_page_body": "We hebben een e-mail naar {{email}} gestuurd. Het is belangrijk om uw e-mailadres te verifiëren om de beste bezorgbaarheid van e-mails en agenda's van {{appName}} te garanderen.",
"verify_email_banner_body": "Verifieer uw e-mailadres om de beste bezorgbaarheid van e-mails en agenda's te garanderen",
"verify_email_email_header": "Verifieer uw e-mailadres",
"verify_email_email_button": "E-mailadres verifiëren",
"verify_email_email_body": "Verifieer uw e-mailadres door op de onderstaande knop te klikken.",
"verify_email_email_link_text": "Hier is de link voor het geval u niet graag op knoppen klikt:",
"email_sent": "E-mail verzonden",
"event_declined_subject": "Afgewezen: {{title}}", "event_declined_subject": "Afgewezen: {{title}}",
"event_cancelled_subject": "Geannuleerd: {{title}} op {{date}}",
"event_request_declined": "Uw gebeurtenisverzoek is geweigerd", "event_request_declined": "Uw gebeurtenisverzoek is geweigerd",
"event_request_declined_recurring": "Uw verzoek voor een terugkerende gebeurtenis is geweigerd", "event_request_declined_recurring": "Uw verzoek voor een terugkerende gebeurtenis is geweigerd",
"event_request_cancelled": "Uw geplande gebeurtenis is geannuleerd",
"organizer": "Organisator", "organizer": "Organisator",
"need_to_reschedule_or_cancel": "Moet u verplaatsen of annuleren?", "need_to_reschedule_or_cancel": "Moet u verplaatsen of annuleren?",
"no_options_available": "Geen opties beschikbaar",
"cancellation_reason": "Reden voor annulering (optioneel)", "cancellation_reason": "Reden voor annulering (optioneel)",
"cancellation_reason_placeholder": "Waarom annuleert u?", "cancellation_reason_placeholder": "Waarom annuleert u?",
"rejection_reason": "Reden voor weigering", "rejection_reason": "Reden voor weigering",
@@ -77,7 +87,9 @@
"your_meeting_has_been_booked": "Uw afspraak is geboekt", "your_meeting_has_been_booked": "Uw afspraak is geboekt",
"event_type_has_been_rescheduled_on_time_date": "Uw {{title}} is verplaatst naar {{date}}.", "event_type_has_been_rescheduled_on_time_date": "Uw {{title}} is verplaatst naar {{date}}.",
"event_has_been_rescheduled": "Bijgewerkt - Uw gebeurtenis is verplaatst", "event_has_been_rescheduled": "Bijgewerkt - Uw gebeurtenis is verplaatst",
"request_reschedule_subtitle": "{{organizer}} heeft de boeking geannuleerd en u verzocht een andere tijd te kiezen.",
"request_reschedule_title_organizer": "U heeft {{attendee}} gevraagd om te verplaatsen", "request_reschedule_title_organizer": "U heeft {{attendee}} gevraagd om te verplaatsen",
"request_reschedule_subtitle_organizer": "U heeft de boeking geannuleerd en {{attendee}} moet samen met u een nieuwe boekingstijd kiezen.",
"rescheduled_event_type_subject": "Verplaatst: {{eventType}} met {{name}} op {{date}}", "rescheduled_event_type_subject": "Verplaatst: {{eventType}} met {{name}} op {{date}}",
"requested_to_reschedule_subject_attendee": "Actie vereist voor verplaatsing: boek een nieuwe tijd voor {{eventType}} met {{name}}", "requested_to_reschedule_subject_attendee": "Actie vereist voor verplaatsing: boek een nieuwe tijd voor {{eventType}} met {{name}}",
"hi_user_name": "Hallo {{name}}", "hi_user_name": "Hallo {{name}}",
@@ -106,6 +118,7 @@
"team_info": "Teaminformatie", "team_info": "Teaminformatie",
"request_another_invitation_email": "Als u {{toEmail}} liever niet als uw {{appName}} e-mail wilt gebruiken of al een {{appName}} account heeft, vraag dan een andere uitnodiging aan voor die e-mail.", "request_another_invitation_email": "Als u {{toEmail}} liever niet als uw {{appName}} e-mail wilt gebruiken of al een {{appName}} account heeft, vraag dan een andere uitnodiging aan voor die e-mail.",
"you_have_been_invited": "U bent uitgenodigd om lid te worden van het team {{teamName}}", "you_have_been_invited": "U bent uitgenodigd om lid te worden van het team {{teamName}}",
"user_invited_you": "{{user}} heeft u uitgenodigd om lid te worden van het {{entity}} {{team}} op {{appName}}",
"hidden_team_member_title": "U bent verborgen in dit team", "hidden_team_member_title": "U bent verborgen in dit team",
"hidden_team_member_message": "Uw plaats is niet betaald. Upgrade naar Pro of laat de teameigenaar weten dat deze uw plaats kan betalen.", "hidden_team_member_message": "Uw plaats is niet betaald. Upgrade naar Pro of laat de teameigenaar weten dat deze uw plaats kan betalen.",
"hidden_team_owner_message": "U heeft een Pro-account nodig om teams te gebruiken, u bent verborgen tot u upgradet.", "hidden_team_owner_message": "U heeft een Pro-account nodig om teams te gebruiken, u bent verborgen tot u upgradet.",
@@ -116,6 +129,8 @@
"team_upgrade_banner_description": "Bedankt voor het testen van ons nieuwe teamabonnement. We hebben geconstateerd dat uw team \"{{teamName}}\" moet worden geüpgraded.", "team_upgrade_banner_description": "Bedankt voor het testen van ons nieuwe teamabonnement. We hebben geconstateerd dat uw team \"{{teamName}}\" moet worden geüpgraded.",
"upgrade_banner_action": "Hier upgraden", "upgrade_banner_action": "Hier upgraden",
"team_upgraded_successfully": "Uw team is geüpgraded!", "team_upgraded_successfully": "Uw team is geüpgraded!",
"org_upgrade_banner_description": "Bedankt voor het testen van ons organisatie-abonnement. We hebben geconstateerd dat uw organisatie \"{{teamName}}\" moet worden geüpgraded.",
"org_upgraded_successfully": "Uw organisatie is geüpgraded!",
"use_link_to_reset_password": "Gebruik de onderstaande link om uw wachtwoord te resetten", "use_link_to_reset_password": "Gebruik de onderstaande link om uw wachtwoord te resetten",
"hey_there": "Hallo daar,", "hey_there": "Hallo daar,",
"forgot_your_password_calcom": "Wachtwoord vergeten? - {{appName}}", "forgot_your_password_calcom": "Wachtwoord vergeten? - {{appName}}",
@@ -182,6 +197,7 @@
"blog": "Blog", "blog": "Blog",
"blog_description": "Lees ons laatste nieuws en artikelen", "blog_description": "Lees ons laatste nieuws en artikelen",
"join_our_community": "Word lid van onze community", "join_our_community": "Word lid van onze community",
"join_our_discord": "Word lid van onze Discord",
"404_claim_entity_user": "Claim uw gebruikersnaam en plan evenementen", "404_claim_entity_user": "Claim uw gebruikersnaam en plan evenementen",
"popular_pages": "Populaire pagina's", "popular_pages": "Populaire pagina's",
"register_now": "Registreer nu", "register_now": "Registreer nu",
@@ -189,6 +205,7 @@
"page_doesnt_exist": "Deze pagina bestaat niet.", "page_doesnt_exist": "Deze pagina bestaat niet.",
"check_spelling_mistakes_or_go_back": "Controleer op spelfouten of ga terug naar de vorige pagina.", "check_spelling_mistakes_or_go_back": "Controleer op spelfouten of ga terug naar de vorige pagina.",
"404_page_not_found": "404: Deze pagina kan niet worden gevonden.", "404_page_not_found": "404: Deze pagina kan niet worden gevonden.",
"booker_event_not_found": "We kunnen de gebeurtenis die u probeert te boeken niet vinden.",
"getting_started": "Aan de slag", "getting_started": "Aan de slag",
"15min_meeting": "15 Minuten afspraak", "15min_meeting": "15 Minuten afspraak",
"30min_meeting": "30 Minuten afspraak", "30min_meeting": "30 Minuten afspraak",
@@ -224,11 +241,14 @@
"done": "Voltooid", "done": "Voltooid",
"all_done": "Helemaal klaar!", "all_done": "Helemaal klaar!",
"all": "Alle apps", "all": "Alle apps",
"yours": "Uw account",
"available_apps": "Beschikbare apps", "available_apps": "Beschikbare apps",
"check_email_reset_password": "Controleer uw e-mail. We hebben u een link gestuurd om uw wachtwoord opnieuw in te stellen.", "check_email_reset_password": "Controleer uw e-mail. We hebben u een link gestuurd om uw wachtwoord opnieuw in te stellen.",
"finish": "Voltooien", "finish": "Voltooien",
"organization_general_description": "Beheer de instellingen voor uw teamtaal en -tijdzone",
"few_sentences_about_yourself": "Een korte introductie over uzelf. Dit wordt weergegeven op uw persoonlijke pagina.", "few_sentences_about_yourself": "Een korte introductie over uzelf. Dit wordt weergegeven op uw persoonlijke pagina.",
"nearly_there": "Bijna klaar!", "nearly_there": "Bijna klaar!",
"nearly_there_instructions": "Tot slot, een korte beschrijving van u en een foto helpt u echt boekingen te krijgen en laat iedereen weten bij wie ze zijn geboekt.",
"set_availability_instructions": "Bepaal tijdbereiken waarin u periodiek beschikbaar bent. U kunt op een later tijdstip terugkomen en hier meer van aanmaken en toewijzen aan verschillende kalenders.", "set_availability_instructions": "Bepaal tijdbereiken waarin u periodiek beschikbaar bent. U kunt op een later tijdstip terugkomen en hier meer van aanmaken en toewijzen aan verschillende kalenders.",
"set_availability": "Beschikbaarheid bepalen", "set_availability": "Beschikbaarheid bepalen",
"continue_without_calendar": "Doorgaan zonder kalender", "continue_without_calendar": "Doorgaan zonder kalender",
@@ -284,6 +304,18 @@
"success": "Geslaagd", "success": "Geslaagd",
"failed": "Mislukt", "failed": "Mislukt",
"password_has_been_reset_login": "Uw wachtwoord is opnieuw ingesteld. U kunt nu inloggen met uw nieuwe wachtwoord.", "password_has_been_reset_login": "Uw wachtwoord is opnieuw ingesteld. U kunt nu inloggen met uw nieuwe wachtwoord.",
"layout": "Indeling",
"bookerlayout_default_title": "Standaardweergave",
"bookerlayout_description": "U kunt er meerdere selecteren en uw boekers kunnen van weergave wisselen.",
"bookerlayout_user_settings_title": "Boekingsindeling",
"bookerlayout_user_settings_description": "U kunt er meerdere selecteren en boekers kunnen van weergave wisselen. Dit kan per gebeurtenis worden aangepast.",
"bookerlayout_month_view": "Maand",
"bookerlayout_week_view": "Wekelijks",
"bookerlayout_column_view": "Kolom",
"bookerlayout_error_min_one_enabled": "Er moet minimaal één indeling ingeschakeld zijn.",
"bookerlayout_error_default_not_enabled": "De indeling die u als standaardweergave heeft geselecteerd, maakt geen deel uit van de ingeschakelde indelingen.",
"bookerlayout_error_unknown_layout": "De door u geselecteerde indeling is geen geldige indeling.",
"bookerlayout_override_global_settings": "U kunt dit voor al uw gebeurtenistypen beheren in <2>Instellingen/Weergave</2> of <6>overschrijven voor alleen deze gebeurtenis</6>.",
"unexpected_error_try_again": "Er is een onverwachte fout opgetreden. Probeer het opnieuw.", "unexpected_error_try_again": "Er is een onverwachte fout opgetreden. Probeer het opnieuw.",
"sunday_time_error": "Ongeldige tijd op zondag", "sunday_time_error": "Ongeldige tijd op zondag",
"monday_time_error": "Ongeldige tijd op maandag", "monday_time_error": "Ongeldige tijd op maandag",
@@ -296,6 +328,7 @@
"error_end_time_next_day": "De eindtijd mag niet meer dan 24 uur later zijn", "error_end_time_next_day": "De eindtijd mag niet meer dan 24 uur later zijn",
"back_to_bookings": "Terug naar afspraken", "back_to_bookings": "Terug naar afspraken",
"free_to_pick_another_event_type": "U kunt op elk moment een andere afspraak maken.", "free_to_pick_another_event_type": "U kunt op elk moment een andere afspraak maken.",
"cancelled": "Geannuleerd",
"cancellation_successful": "Annulering geslaagd", "cancellation_successful": "Annulering geslaagd",
"really_cancel_booking": "Weet u zeker dat u deze afspraak wilt annuleren?", "really_cancel_booking": "Weet u zeker dat u deze afspraak wilt annuleren?",
"cannot_cancel_booking": "U kunt deze afspraak niet annuleren", "cannot_cancel_booking": "U kunt deze afspraak niet annuleren",
@@ -304,6 +337,12 @@
"cancelling_event_recurring": "De gebeurtenis is één exemplaar van een terugkerende gebeurtenis.", "cancelling_event_recurring": "De gebeurtenis is één exemplaar van een terugkerende gebeurtenis.",
"cancelling_all_recurring": "Dit zijn alle resterende exemplaren van de terugkerende gebeurtenis.", "cancelling_all_recurring": "Dit zijn alle resterende exemplaren van de terugkerende gebeurtenis.",
"error_with_status_code_occured": "Er is een fout opgetreden met de code {{status}}.", "error_with_status_code_occured": "Er is een fout opgetreden met de code {{status}}.",
"error_event_type_url_duplicate": "Er bestaat al een gebeurtenistype met deze URL.",
"error_event_type_unauthorized_create": "U kunt deze gebeurtenis niet maken",
"error_event_type_unauthorized_update": "U kunt deze gebeurtenis niet bewerken",
"error_workflow_unauthorized_create": "U kunt deze werkstroom niet maken",
"error_schedule_unauthorized_create": "U kunt deze planning niet maken",
"booking_already_cancelled": "Deze boeking is al geannuleerd",
"booking_already_accepted_rejected": "Deze boeking is al geaccepteerd of geweigerd", "booking_already_accepted_rejected": "Deze boeking is al geaccepteerd of geweigerd",
"go_back_home": "Terug naar startpagina", "go_back_home": "Terug naar startpagina",
"or_go_back_home": "Of ga terug naar de startpagina", "or_go_back_home": "Of ga terug naar de startpagina",
@@ -313,10 +352,12 @@
"no_status_bookings_yet_description": "U heeft nog geen {{status}} afspraken. {{description}}", "no_status_bookings_yet_description": "U heeft nog geen {{status}} afspraken. {{description}}",
"event_between_users": "{{eventName}} tussen {{host}} en {{attendeeName}}", "event_between_users": "{{eventName}} tussen {{host}} en {{attendeeName}}",
"bookings": "Afspraken", "bookings": "Afspraken",
"booking_not_found": "Boeking niet gevonden",
"bookings_description": "Bekijk geplande en voorgaande afspraken die geboekt zijn door middel van uw links.", "bookings_description": "Bekijk geplande en voorgaande afspraken die geboekt zijn door middel van uw links.",
"upcoming_bookings": "Zodra iemand een tijd boekt zal deze hier verschijnen.", "upcoming_bookings": "Zodra iemand een tijd boekt zal deze hier verschijnen.",
"recurring_bookings": "Zodra iemand een terugkerende afspraak met u boekt, verschijnt die hier.", "recurring_bookings": "Zodra iemand een terugkerende afspraak met u boekt, verschijnt die hier.",
"past_bookings": "Uw oude afspraken zullen hier verschijnen.", "past_bookings": "Uw oude afspraken zullen hier verschijnen.",
"cancelled_bookings": "Uw geannuleerde boekingen worden hier weergegeven.",
"unconfirmed_bookings": "Uw niet-bevestigde afspraken zullen hier verschijnen.", "unconfirmed_bookings": "Uw niet-bevestigde afspraken zullen hier verschijnen.",
"unconfirmed_bookings_tooltip": "Niet-bevestigde boekingen", "unconfirmed_bookings_tooltip": "Niet-bevestigde boekingen",
"on": "aan", "on": "aan",
@@ -350,15 +391,19 @@
"user_dynamic_booking_disabled": "Sommige gebruikers in de groep hebben momenteel dynamische groepsboekingen uitgeschakeld", "user_dynamic_booking_disabled": "Sommige gebruikers in de groep hebben momenteel dynamische groepsboekingen uitgeschakeld",
"allow_dynamic_booking_tooltip": "Groepsboekingslinks die dynamisch kunnen worden aangemaakt door meerdere gebruikersnamen toe te voegen met een \"+\", bijvoorbeeld: \"{{appName}}/bailey+peer", "allow_dynamic_booking_tooltip": "Groepsboekingslinks die dynamisch kunnen worden aangemaakt door meerdere gebruikersnamen toe te voegen met een \"+\", bijvoorbeeld: \"{{appName}}/bailey+peer",
"allow_dynamic_booking": "Sta deelnemers toe om u te boeken via dynamische groepsboekingen", "allow_dynamic_booking": "Sta deelnemers toe om u te boeken via dynamische groepsboekingen",
"dynamic_booking": "Dynamische groepslinks",
"email": "E-mailadres", "email": "E-mailadres",
"email_placeholder": "jjansen@voorbeeld.nl", "email_placeholder": "jjansen@voorbeeld.nl",
"full_name": "Volledige naam", "full_name": "Volledige naam",
"browse_api_documentation": "Bekijk onze API-documentatie", "browse_api_documentation": "Bekijk onze API-documentatie",
"leverage_our_api": "Gebruik onze API voor volledige controle en aanpasbaarheid.", "leverage_our_api": "Gebruik onze API voor volledige controle en aanpasbaarheid.",
"create_webhook": "Webhook maken", "create_webhook": "Webhook maken",
"booking_cancelled": "Boeking geannuleerd",
"booking_rescheduled": "Afspraak verplaatst", "booking_rescheduled": "Afspraak verplaatst",
"recording_ready": "Opnamedownloadlink gereed", "recording_ready": "Opnamedownloadlink gereed",
"booking_created": "Boeking aangemaakt", "booking_created": "Boeking aangemaakt",
"booking_rejected": "Boeking geweigerd",
"booking_requested": "Boeking aangevraagd",
"meeting_ended": "Vergadering beëindigd", "meeting_ended": "Vergadering beëindigd",
"form_submitted": "Formulier verzonden", "form_submitted": "Formulier verzonden",
"event_triggers": "Webhook activaties", "event_triggers": "Webhook activaties",
@@ -368,6 +413,8 @@
"team_webhooks": "Teamwebhooks", "team_webhooks": "Teamwebhooks",
"create_new_webhook_to_account": "Maak een nieuwe webhook aan voor uw account", "create_new_webhook_to_account": "Maak een nieuwe webhook aan voor uw account",
"new_webhook": "Maak een Webhook", "new_webhook": "Maak een Webhook",
"receive_cal_meeting_data": "Ontvang {{appName}}-afspraakgegevens in realtime via een opgegeven URL wanneer een gebeurtenis wordt gepland of geannuleerd.",
"receive_cal_event_meeting_data": "Ontvang {{appName}}-afspraakgegevens in realtime via een opgegeven URL wanneer een gebeurtenis wordt gepland of geannuleerd.",
"responsive_fullscreen_iframe": "Responsieve iframe", "responsive_fullscreen_iframe": "Responsieve iframe",
"loading": "Laden...", "loading": "Laden...",
"deleting": "Verwijderen...", "deleting": "Verwijderen...",
@@ -430,6 +477,7 @@
"max_limit_allowed_hint": "Moet {{limit}}} of minder tekens lang zijn", "max_limit_allowed_hint": "Moet {{limit}}} of minder tekens lang zijn",
"invalid_password_hint": "Het wachtwoord moet minimaal {{passwordLength}} tekens lang zijn, minimaal 1 cijfer bevatten en bestaan uit een mix van hoofd- en kleine letters", "invalid_password_hint": "Het wachtwoord moet minimaal {{passwordLength}} tekens lang zijn, minimaal 1 cijfer bevatten en bestaan uit een mix van hoofd- en kleine letters",
"incorrect_password": "Uw wachtwoord is incorrect.", "incorrect_password": "Uw wachtwoord is incorrect.",
"incorrect_email_password": "E-mailadres of wachtwoord is onjuist.",
"use_setting": "Instelling gebruiken", "use_setting": "Instelling gebruiken",
"am_pm": "am/pm", "am_pm": "am/pm",
"time_options": "Tijd, datum en tijdzone instellen", "time_options": "Tijd, datum en tijdzone instellen",
@@ -457,6 +505,7 @@
"additional_guests": "Gasten toevoegen", "additional_guests": "Gasten toevoegen",
"your_name": "Uw naam", "your_name": "Uw naam",
"your_full_name": "Uw volledige naam", "your_full_name": "Uw volledige naam",
"no_name": "Geen naam",
"email_address": "E-mail adres", "email_address": "E-mail adres",
"enter_valid_email": "Voer een geldig e-mailadres in", "enter_valid_email": "Voer een geldig e-mailadres in",
"location": "Locatie", "location": "Locatie",
@@ -500,10 +549,13 @@
"your_team_updated_successfully": "Uw team is succesvol bijgewerkt.", "your_team_updated_successfully": "Uw team is succesvol bijgewerkt.",
"about": "Introductie", "about": "Introductie",
"team_description": "Een paar zinnen over uw team. Dit is zichtbaar op uw teampagina.", "team_description": "Een paar zinnen over uw team. Dit is zichtbaar op uw teampagina.",
"org_description": "Een paar zinnen over uw organisatie. Dit wordt weergegeven op op uw organisatiepagina.",
"members": "Leden", "members": "Leden",
"organization_members": "Organisatieleden",
"member": "Lid", "member": "Lid",
"number_member_one": "{{count}} lid", "number_member_one": "{{count}} lid",
"number_member_other": "{{count}} leden", "number_member_other": "{{count}} leden",
"number_selected": "{{count}} geselecteerd",
"owner": "Eigenaar", "owner": "Eigenaar",
"admin": "Beheerder", "admin": "Beheerder",
"administrator_user": "Beheerdersgebruiker", "administrator_user": "Beheerdersgebruiker",
@@ -534,6 +586,8 @@
"confirm_all": "Alles bevestigen", "confirm_all": "Alles bevestigen",
"disband_team": "Team ontbinden", "disband_team": "Team ontbinden",
"disband_team_confirmation_message": "Weet u zeker dat u dit team wilt ontbinden? Iedereen met wie u deze teampagina heeft gedeeld zal hem niet meer kunnen gebruiken om te boeken.", "disband_team_confirmation_message": "Weet u zeker dat u dit team wilt ontbinden? Iedereen met wie u deze teampagina heeft gedeeld zal hem niet meer kunnen gebruiken om te boeken.",
"disband_org": "Organisatie ontbinden",
"disband_org_confirmation_message": "Weet u zeker dat u deze organisatie wilt ontbinden? Alle teams en leden worden verwijderd.",
"remove_member_confirmation_message": "Weet u zeker dat u dit lid uit het team wilt verwijderen?", "remove_member_confirmation_message": "Weet u zeker dat u dit lid uit het team wilt verwijderen?",
"confirm_disband_team": "Ja, ontbind team", "confirm_disband_team": "Ja, ontbind team",
"confirm_remove_member": "Ja, verwijder lid", "confirm_remove_member": "Ja, verwijder lid",
@@ -608,6 +662,7 @@
"event_type_updated_successfully": "Evenement is bijgewerkt", "event_type_updated_successfully": "Evenement is bijgewerkt",
"event_type_deleted_successfully": "Evenement is verwijderd", "event_type_deleted_successfully": "Evenement is verwijderd",
"hours": "Uren", "hours": "Uren",
"people": "Mensen",
"your_email": "Uw E-mailadres", "your_email": "Uw E-mailadres",
"change_avatar": "Wijzig avatar", "change_avatar": "Wijzig avatar",
"language": "Taal", "language": "Taal",
@@ -640,9 +695,11 @@
"create_new_team": "Nieuw team aanmaken", "create_new_team": "Nieuw team aanmaken",
"open_invitations": "Openstaande uitnodigingen", "open_invitations": "Openstaande uitnodigingen",
"new_team": "Nieuw Team", "new_team": "Nieuw Team",
"create_first_team_and_invite_others": "Maak uw eerste team en nodig andere gebruikers uit om samen te werken.",
"create_team_to_get_started": "Maak een team aan om aan de slag te gaan", "create_team_to_get_started": "Maak een team aan om aan de slag te gaan",
"teams": "Teams", "teams": "Teams",
"team": "Team", "team": "Team",
"organization": "Organisatie",
"team_billing": "Teamfacturatie", "team_billing": "Teamfacturatie",
"team_billing_description": "Beheer de facturering voor uw team", "team_billing_description": "Beheer de facturering voor uw team",
"upgrade_to_flexible_pro_title": "We hebben het factureren gewijzigd voor teams", "upgrade_to_flexible_pro_title": "We hebben het factureren gewijzigd voor teams",
@@ -717,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}} zal een Huddle01 web3 meeting-URL meegeven in de afspraak bevestiging.", "cal_provide_huddle01_meeting_url": "{{appName}} zal een Huddle01 web3 meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_teams_meeting_url": "{{appName}} geeft een vergaderings-URL voor MS Teams. OPMERKING: MOET EEN WERK- OF SCHOOLACCOUNT HEBBEN", "cal_provide_teams_meeting_url": "{{appName}} geeft een vergaderings-URL voor MS Teams. OPMERKING: MOET EEN WERK- OF SCHOOLACCOUNT HEBBEN",
"require_payment": "Betaling vereisen", "require_payment": "Betaling vereisen",
"you_need_to_add_a_name": "U moet een naam toevoegen",
"commission_per_transaction": "commissie per transactie", "commission_per_transaction": "commissie per transactie",
"event_type_updated_successfully_description": "Uw evenement is met succes bijgewerkt.", "event_type_updated_successfully_description": "Uw evenement is met succes bijgewerkt.",
"hide_event_type": "Verberg evenement", "hide_event_type": "Verberg evenement",
@@ -807,18 +865,25 @@
"installed_apps": "Geinstalleerde apps", "installed_apps": "Geinstalleerde apps",
"free_to_use_apps": "Gratis", "free_to_use_apps": "Gratis",
"no_category_apps": "Geen apps voor {{category}}", "no_category_apps": "Geen apps voor {{category}}",
"all_apps": "Alle apps",
"no_category_apps_description_calendar": "Voeg een agenda-app toe om te controleren op conflicten om dubbele boekingen te voorkomen", "no_category_apps_description_calendar": "Voeg een agenda-app toe om te controleren op conflicten om dubbele boekingen te voorkomen",
"no_category_apps_description_conferencing": "Probeer een conferentieapp toe te voegen voor videogesprekken met uw klanten",
"no_category_apps_description_payment": "Voeg een betaalapp toe om transacties tussen u en uw klanten te vergemakkelijken", "no_category_apps_description_payment": "Voeg een betaalapp toe om transacties tussen u en uw klanten te vergemakkelijken",
"no_category_apps_description_analytics": "Voeg een analyse-app toe aan uw boekingspagina's", "no_category_apps_description_analytics": "Voeg een analyse-app toe aan uw boekingspagina's",
"no_category_apps_description_automation": "Voeg een automatiseringsapp toe om te gebruiken", "no_category_apps_description_automation": "Voeg een automatiseringsapp toe om te gebruiken",
"no_category_apps_description_other": "Voeg een ander type app toe om allerlei soorten dingen te doen", "no_category_apps_description_other": "Voeg een ander type app toe om allerlei soorten dingen te doen",
"no_category_apps_description_web3": "Voeg een web3-app toe aan uw boekingspagina's", "no_category_apps_description_web3": "Voeg een web3-app toe aan uw boekingspagina's",
"no_category_apps_description_messaging": "Voeg een berichtenapp toe om aangepaste meldingen en herinneringen in te stellen",
"no_category_apps_description_crm": "Voeg een CRM-app toe om bij te houden met wie u heeft ontmoet",
"installed_app_calendar_description": "Stel de agenda('s) in om te controleren op conflicten om dubbele boekingen te voorkomen.", "installed_app_calendar_description": "Stel de agenda('s) in om te controleren op conflicten om dubbele boekingen te voorkomen.",
"installed_app_payment_description": "Configureer welke betalingsverwerkingsdiensten u wilt gebruiken bij het factureren aan uw klanten.", "installed_app_payment_description": "Configureer welke betalingsverwerkingsdiensten u wilt gebruiken bij het factureren aan uw klanten.",
"installed_app_analytics_description": "Configureer welke analyse-apps moeten worden gebruikt voor uw boekingspagina's", "installed_app_analytics_description": "Configureer welke analyse-apps moeten worden gebruikt voor uw boekingspagina's",
"installed_app_other_description": "Alle geïnstalleerde apps uit andere categorieën.", "installed_app_other_description": "Alle geïnstalleerde apps uit andere categorieën.",
"installed_app_conferencing_description": "Configureer welke conferentieapps moeten worden gebruikt",
"installed_app_automation_description": "Configureer welke automatiseringsapps moeten worden gebruikt", "installed_app_automation_description": "Configureer welke automatiseringsapps moeten worden gebruikt",
"installed_app_web3_description": "Configureer welke web3-apps moeten worden gebruikt voor uw boekingspagina's", "installed_app_web3_description": "Configureer welke web3-apps moeten worden gebruikt voor uw boekingspagina's",
"installed_app_messaging_description": "Configureer welke berichtenapps moeten worden gebruikt voor het instellen van aangepaste meldingen en herinneringen",
"installed_app_crm_description": "Configureer welke CRM-apps moeten worden gebruikt voor het bijhouden van wie u hebt ontmoet",
"analytics": "Analyse", "analytics": "Analyse",
"empty_installed_apps_headline": "Geen apps geïnstalleerd", "empty_installed_apps_headline": "Geen apps geïnstalleerd",
"empty_installed_apps_description": "Met apps kunt u uw workflow en uw planning aanzienlijk verbeteren.", "empty_installed_apps_description": "Met apps kunt u uw workflow en uw planning aanzienlijk verbeteren.",
@@ -844,6 +909,7 @@
"create_events_on": "Maak gebeurtenissen aan in de", "create_events_on": "Maak gebeurtenissen aan in de",
"enterprise_license": "Dit is een bedrijfsfunctie", "enterprise_license": "Dit is een bedrijfsfunctie",
"enterprise_license_description": "Om deze functie in te schakelen, krijgt u een implementatiesleutel op de {{consoleUrl}}-console en voegt u deze toe aan uw .env als CALCOM_LICENSE_KEY. Als uw team al een licentie heeft, neem dan contact op met {{supportMail}} voor hulp.", "enterprise_license_description": "Om deze functie in te schakelen, krijgt u een implementatiesleutel op de {{consoleUrl}}-console en voegt u deze toe aan uw .env als CALCOM_LICENSE_KEY. Als uw team al een licentie heeft, neem dan contact op met {{supportMail}} voor hulp.",
"enterprise_license_development": "U kunt deze functie in ontwikkelingsmodus testen. Voor productiegebruik moet een beheerder naar <2>/auth/setup</2> gaan om een licentiesleutel in te voeren.",
"missing_license": "Ontbrekende licentie", "missing_license": "Ontbrekende licentie",
"signup_requires": "Commerciële licentie vereist", "signup_requires": "Commerciële licentie vereist",
"signup_requires_description": "{{companyName}} biedt momenteel geen gratis opensourceversie van de registratiepagina aan. Om volledige toegang te krijgen tot de registratieonderdelen moet u een commerciële licentie verkrijgen. Voor persoonlijk gebruik raden we aan om accounts aan te maken op het Prisma Data Platform of een andere Postgres-interface.", "signup_requires_description": "{{companyName}} biedt momenteel geen gratis opensourceversie van de registratiepagina aan. Om volledige toegang te krijgen tot de registratieonderdelen moet u een commerciële licentie verkrijgen. Voor persoonlijk gebruik raden we aan om accounts aan te maken op het Prisma Data Platform of een andere Postgres-interface.",
@@ -913,6 +979,7 @@
"confirm_delete_api_key": "Deze API-sleutel intrekken", "confirm_delete_api_key": "Deze API-sleutel intrekken",
"revoke_api_key": "API-sleutel intrekken", "revoke_api_key": "API-sleutel intrekken",
"api_key_copied": "API-sleutel gekopieerd!", "api_key_copied": "API-sleutel gekopieerd!",
"api_key_expires_on": "De API-sleutel verloopt op",
"delete_api_key_confirm_title": "Deze API-sleutel permanent van uw account verwijderen?", "delete_api_key_confirm_title": "Deze API-sleutel permanent van uw account verwijderen?",
"copy": "Kopiëren", "copy": "Kopiëren",
"expire_date": "Verloopdatum", "expire_date": "Verloopdatum",
@@ -935,6 +1002,9 @@
"user_impersonation_heading": "Imitatie van gebruiker", "user_impersonation_heading": "Imitatie van gebruiker",
"user_impersonation_description": "Hiermee kan ons ondersteuningsteam tijdelijk als u inloggen zodat we eventuele problemen die u aan ons meldt snel op kunnen lossen.", "user_impersonation_description": "Hiermee kan ons ondersteuningsteam tijdelijk als u inloggen zodat we eventuele problemen die u aan ons meldt snel op kunnen lossen.",
"team_impersonation_description": "Hiermee kunnen uw teamleden zich tijdelijk aanmelden als u.", "team_impersonation_description": "Hiermee kunnen uw teamleden zich tijdelijk aanmelden als u.",
"make_team_private": "Team privé maken",
"make_team_private_description": "Uw teamleden kunnen geen andere teamleden zien wanneer dit ingeschakeld is.",
"you_cannot_see_team_members": "U kunt niet alle teamleden van een privéteam zien.",
"allow_booker_to_select_duration": "Booker toestaan om een duur te selecteren", "allow_booker_to_select_duration": "Booker toestaan om een duur te selecteren",
"impersonate_user_tip": "Alle gebruik van deze functie wordt gecontroleerd.", "impersonate_user_tip": "Alle gebruik van deze functie wordt gecontroleerd.",
"impersonating_user_warning": "Gebruikersnaam \"{{user}}\" wordt geïmiteerd.", "impersonating_user_warning": "Gebruikersnaam \"{{user}}\" wordt geïmiteerd.",
@@ -1002,16 +1072,21 @@
"event_location": "Locatie gebeurtenis", "event_location": "Locatie gebeurtenis",
"reschedule_optional": "Reden voor verplaatsen (optioneel)", "reschedule_optional": "Reden voor verplaatsen (optioneel)",
"reschedule_placeholder": "Informeer anderen waarom u het moet verplaatsen", "reschedule_placeholder": "Informeer anderen waarom u het moet verplaatsen",
"event_cancelled": "Deze gebeurtenis is geannuleerd",
"emailed_information_about_cancelled_event": "We hebben u en de andere deelnemers een e-mail gestuurd om hen te informeren.", "emailed_information_about_cancelled_event": "We hebben u en de andere deelnemers een e-mail gestuurd om hen te informeren.",
"this_input_will_shown_booking_this_event": "Deze invoer wordt getoond tijdens het boeken van dit evenement", "this_input_will_shown_booking_this_event": "Deze invoer wordt getoond tijdens het boeken van dit evenement",
"meeting_url_in_conformation_email": "De vergader-URL wordt vermeld in de bevestigings-e-mail", "meeting_url_in_conformation_email": "De vergader-URL wordt vermeld in de bevestigings-e-mail",
"url_start_with_https": "URL moet beginnen met http:// of https://", "url_start_with_https": "URL moet beginnen met http:// of https://",
"number_provided": "Telefoonnummer wordt verstrekt", "number_provided": "Telefoonnummer wordt verstrekt",
"before_event_trigger": "voordat de gebeurtenis begint", "before_event_trigger": "voordat de gebeurtenis begint",
"event_cancelled_trigger": "wanneer de gebeurtenis is geannuleerd",
"new_event_trigger": "wanneer een nieuwe gebeurtenis is geboekt", "new_event_trigger": "wanneer een nieuwe gebeurtenis is geboekt",
"email_host_action": "e-mail naar organisator versturen", "email_host_action": "e-mail naar organisator versturen",
"email_attendee_action": "e-mail naar deelnemers versturen", "email_attendee_action": "e-mail naar deelnemers versturen",
"sms_attendee_action": "Sms naar deelnemer versturen",
"sms_number_action": "sms naar een specifiek nummer sturen", "sms_number_action": "sms naar een specifiek nummer sturen",
"whatsapp_number_action": "WhatsApp-bericht naar een specifiek nummer versturen",
"whatsapp_attendee_action": "WhatsApp-bericht naar deelnemer versturen",
"workflows": "Werkstromen", "workflows": "Werkstromen",
"new_workflow_btn": "Nieuwe werkstroom", "new_workflow_btn": "Nieuwe werkstroom",
"add_new_workflow": "Een nieuwe werkstroom toevoegen", "add_new_workflow": "Een nieuwe werkstroom toevoegen",
@@ -1075,6 +1150,8 @@
"choose_template": "Kies een sjabloon", "choose_template": "Kies een sjabloon",
"custom": "Aangepast", "custom": "Aangepast",
"reminder": "Herinnering", "reminder": "Herinnering",
"rescheduled": "Opnieuw gepland",
"completed": "Voltooid",
"reminder_email": "Herinnering: {{eventType}} met {{name}} op {{date}}", "reminder_email": "Herinnering: {{eventType}} met {{name}} op {{date}}",
"not_triggering_existing_bookings": "Wordt niet geactiveerd voor bestaande boekingen, omdat de gebruiker om zijn/haar telefoonnummer gevraagd wordt bij het boeken van de gebeurtenis.", "not_triggering_existing_bookings": "Wordt niet geactiveerd voor bestaande boekingen, omdat de gebruiker om zijn/haar telefoonnummer gevraagd wordt bij het boeken van de gebeurtenis.",
"minute_one": "{{count}} minuut", "minute_one": "{{count}} minuut",
@@ -1172,6 +1249,7 @@
"start_of_week": "Begin van de week", "start_of_week": "Begin van de week",
"recordings_title": "Opnames", "recordings_title": "Opnames",
"recording": "Opname", "recording": "Opname",
"happy_scheduling": "Veel plezier met plannen",
"select_calendars": "Selecteer de agenda's die u wilt controleren op conflicten om dubbele boekingen te voorkomen.", "select_calendars": "Selecteer de agenda's die u wilt controleren op conflicten om dubbele boekingen te voorkomen.",
"check_for_conflicts": "Controleer op conflicten", "check_for_conflicts": "Controleer op conflicten",
"view_recordings": "Opnames weergeven", "view_recordings": "Opnames weergeven",
@@ -1213,6 +1291,7 @@
"conferencing_description": "Beheer uw favoriete apps voor videoconferenties voor uw vergaderingen", "conferencing_description": "Beheer uw favoriete apps voor videoconferenties voor uw vergaderingen",
"add_conferencing_app": "Conferentieapp toevoegen", "add_conferencing_app": "Conferentieapp toevoegen",
"password_description": "Beheer de instellingen voor uw accountwachtwoorden", "password_description": "Beheer de instellingen voor uw accountwachtwoorden",
"set_up_two_factor_authentication": "Stel uw tweestapsverificatie in",
"we_just_need_basic_info": "We hebben alleen wat basisinformatie nodig om uw profiel te kunnen configureren.", "we_just_need_basic_info": "We hebben alleen wat basisinformatie nodig om uw profiel te kunnen configureren.",
"skip": "Overslaan", "skip": "Overslaan",
"do_this_later": "Doe dit later", "do_this_later": "Doe dit later",
@@ -1226,6 +1305,8 @@
"connect_analytics_apps": "Koppel analyse-apps", "connect_analytics_apps": "Koppel analyse-apps",
"connect_other_apps": "Andere apps koppelen", "connect_other_apps": "Andere apps koppelen",
"connect_web3_apps": "Web3-apps koppelen", "connect_web3_apps": "Web3-apps koppelen",
"connect_messaging_apps": "Berichtenapps koppelen",
"connect_crm_apps": "CRM-apps koppelen",
"current_step_of_total": "Stap {{currentStep}} van {{maxSteps}}", "current_step_of_total": "Stap {{currentStep}} van {{maxSteps}}",
"add_variable": "Variabele toevoegen", "add_variable": "Variabele toevoegen",
"custom_phone_number": "Aangepast telefoonnummer", "custom_phone_number": "Aangepast telefoonnummer",
@@ -1238,12 +1319,14 @@
"location_info": "De locatie van de gebeurtenis", "location_info": "De locatie van de gebeurtenis",
"additional_notes_info": "De aanvullende opmerkingen bij de boeking", "additional_notes_info": "De aanvullende opmerkingen bij de boeking",
"attendee_name_info": "De naam van de persoon die boekt", "attendee_name_info": "De naam van de persoon die boekt",
"organizer_name_info": "Naam organisator",
"to": "Aan", "to": "Aan",
"workflow_turned_on_successfully": "De werkstroom {{workflowName}} is {{offOn}}", "workflow_turned_on_successfully": "De werkstroom {{workflowName}} is {{offOn}}",
"download_responses": "Reacties downloaden", "download_responses": "Reacties downloaden",
"download_responses_description": "Download alle reacties op uw formulier in CSV-indeling.", "download_responses_description": "Download alle reacties op uw formulier in CSV-indeling.",
"download": "Downloaden", "download": "Downloaden",
"download_recording": "Opname downloaden", "download_recording": "Opname downloaden",
"recording_from_your_recent_call": "Een opname van uw recente gesprek op {{appName}} is klaar om te downloaden",
"create_your_first_form": "Maak uw eerste formulier", "create_your_first_form": "Maak uw eerste formulier",
"create_your_first_form_description": "Met routeringsformulieren kunt u kwalificerende vragen stellen en doorverwijzen naar de juiste persoon of het juiste type gebeurtenis.", "create_your_first_form_description": "Met routeringsformulieren kunt u kwalificerende vragen stellen en doorverwijzen naar de juiste persoon of het juiste type gebeurtenis.",
"create_your_first_webhook": "Maak uw eerste webhook", "create_your_first_webhook": "Maak uw eerste webhook",
@@ -1252,7 +1335,9 @@
"event_one": "gebeurtenis", "event_one": "gebeurtenis",
"event_other": "gebeurtenissen", "event_other": "gebeurtenissen",
"profile_team_description": "Beheer de instellingen van uw teamprofiel", "profile_team_description": "Beheer de instellingen van uw teamprofiel",
"profile_org_description": "Beheer de instellingen van uw organisatieprofiel",
"members_team_description": "Gebruikers in de groep", "members_team_description": "Gebruikers in de groep",
"organization_description": "Beheer de beheerders en leden in uw organisatie",
"team_url": "Team-URL", "team_url": "Team-URL",
"team_members": "Teamleden", "team_members": "Teamleden",
"more": "Meer", "more": "Meer",
@@ -1293,6 +1378,7 @@
"routing_forms_send_email_owner": "E-mail naar eigenaar versturen", "routing_forms_send_email_owner": "E-mail naar eigenaar versturen",
"routing_forms_send_email_owner_description": "Verstuurt een e-mail naar de eigenaar wanneer het formulier is verzonden", "routing_forms_send_email_owner_description": "Verstuurt een e-mail naar de eigenaar wanneer het formulier is verzonden",
"add_new_form": "Nieuw formulier toevoegen", "add_new_form": "Nieuw formulier toevoegen",
"add_new_team_form": "Voeg een nieuw formulier toe aan uw team",
"create_your_first_route": "Maak uw eerste route", "create_your_first_route": "Maak uw eerste route",
"route_to_the_right_person": "Route naar de juiste persoon op basis van de antwoorden op uw formulier", "route_to_the_right_person": "Route naar de juiste persoon op basis van de antwoorden op uw formulier",
"form_description": "Maak uw formulier om naar een boeker door te verwijzen", "form_description": "Maak uw formulier om naar een boeker door te verwijzen",
@@ -1378,6 +1464,7 @@
"new_event_type_availability": "Beschikbaarheid {{eventTypeTitle}}", "new_event_type_availability": "Beschikbaarheid {{eventTypeTitle}}",
"error_editing_availability": "Fout bij het bewerken van de beschikbaarheid", "error_editing_availability": "Fout bij het bewerken van de beschikbaarheid",
"dont_have_permission": "U heeft geen machting voor toegang tot dit hulpmiddel.", "dont_have_permission": "U heeft geen machting voor toegang tot dit hulpmiddel.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Plak de SAML-metagegevens van uw identiteitsprovider hier", "saml_configuration_placeholder": "Plak de SAML-metagegevens van uw identiteitsprovider hier",
"saml_email_required": "Voer een e-mailadres in zodat we uw SAML-identiteitsprovider kunnen vinden", "saml_email_required": "Voer een e-mailadres in zodat we uw SAML-identiteitsprovider kunnen vinden",
"saml_sp_title": "Serviceprovidergegevens", "saml_sp_title": "Serviceprovidergegevens",
@@ -1396,15 +1483,19 @@
"yearly": "Jaarlijks", "yearly": "Jaarlijks",
"checkout": "Kassa", "checkout": "Kassa",
"your_team_disbanded_successfully": "Uw team is ontbonden", "your_team_disbanded_successfully": "Uw team is ontbonden",
"your_org_disbanded_successfully": "Uw organisatie is ontbonden",
"error_creating_team": "Fout bij het aanmaken van team", "error_creating_team": "Fout bij het aanmaken van team",
"you": "U", "you": "U",
"resend_email": "E-mail opnieuw versturen",
"member_already_invited": "Lid is al uitgenodigd", "member_already_invited": "Lid is al uitgenodigd",
"enter_email_or_username": "Voer een e-mailadres of gebruikersnaam in", "enter_email_or_username": "Voer een e-mailadres of gebruikersnaam in",
"team_name_taken": "Deze naam is al in gebruik", "team_name_taken": "Deze naam is al in gebruik",
"must_enter_team_name": "Moet een teamnaam invoeren", "must_enter_team_name": "Moet een teamnaam invoeren",
"team_url_required": "Moet een team-URL invoeren", "team_url_required": "Moet een team-URL invoeren",
"url_taken": "Deze URL is al in gebruik", "url_taken": "Deze URL is al in gebruik",
"problem_registering_domain": "Er is een probleem opgetreden bij het registreren van het subdomein, probeer het opnieuw of neem contact op met een beheerder",
"team_publish": "Team publiceren", "team_publish": "Team publiceren",
"number_text_notifications": "Telefoonnummer (berichtmeldingen)",
"attendee_email_variable": "E-mailadres deelnemer", "attendee_email_variable": "E-mailadres deelnemer",
"attendee_email_info": "Het e-mailadres van de persoon die boekt", "attendee_email_info": "Het e-mailadres van de persoon die boekt",
"kbar_search_placeholder": "Typ een opdracht of zoek...", "kbar_search_placeholder": "Typ een opdracht of zoek...",
@@ -1427,6 +1518,8 @@
"find_the_best_person": "Zoek de beste beschikbare persoon en blader door uw team.", "find_the_best_person": "Zoek de beste beschikbare persoon en blader door uw team.",
"fixed_round_robin": "Vaste round-robin", "fixed_round_robin": "Vaste round-robin",
"add_one_fixed_attendee": "Voeg één vaste deelnemer en round-robin toe via een aantal deelnemers.", "add_one_fixed_attendee": "Voeg één vaste deelnemer en round-robin toe via een aantal deelnemers.",
"calcom_is_better_with_team": "{{appName}} is beter met teams",
"the_calcom_team": "Het {{companyName}}-team",
"add_your_team_members": "Voeg uw teamleden toe aan uw gebeurtenistypes. Gebruik collectieve planning om iedereen op te nemen of zoek de meest geschikte persoon met round robin-planning.", "add_your_team_members": "Voeg uw teamleden toe aan uw gebeurtenistypes. Gebruik collectieve planning om iedereen op te nemen of zoek de meest geschikte persoon met round robin-planning.",
"booking_limit_reached": "Boekingslimiet voor dit gebeurtenistype is bereikt", "booking_limit_reached": "Boekingslimiet voor dit gebeurtenistype is bereikt",
"duration_limit_reached": "Duurlimiet voor dit gebeurtenistype is bereikt", "duration_limit_reached": "Duurlimiet voor dit gebeurtenistype is bereikt",
@@ -1445,6 +1538,7 @@
"navigate_installed_apps": "Naar geïnstalleerde apps", "navigate_installed_apps": "Naar geïnstalleerde apps",
"disabled_calendar": "Als u een andere agenda heeft geïnstalleerd, worden nieuwe boekingen daaraan toegevoegd. Zo niet, koppel dan een nieuwe agenda zodat u geen nieuwe boekingen mist.", "disabled_calendar": "Als u een andere agenda heeft geïnstalleerd, worden nieuwe boekingen daaraan toegevoegd. Zo niet, koppel dan een nieuwe agenda zodat u geen nieuwe boekingen mist.",
"enable_apps": "Apps inschakelen", "enable_apps": "Apps inschakelen",
"enable_apps_description": "Schakel apps in die gebruikers kunnen integreren met {{appName}}",
"purchase_license": "Koop een licentie", "purchase_license": "Koop een licentie",
"already_have_key": "Ik heb al een code:", "already_have_key": "Ik heb al een code:",
"already_have_key_suggestion": "Kopieer hier uw bestaande CALCOM_LICENSE_KEY-omgevingsvariabele.", "already_have_key_suggestion": "Kopieer hier uw bestaande CALCOM_LICENSE_KEY-omgevingsvariabele.",
@@ -1458,6 +1552,9 @@
"no_available_apps": "Er zijn geen beschikbare apps", "no_available_apps": "Er zijn geen beschikbare apps",
"no_available_apps_description": "Zorg ervoor dat er apps zijn in uw implementatie onder \"packages/app-store\"", "no_available_apps_description": "Zorg ervoor dat er apps zijn in uw implementatie onder \"packages/app-store\"",
"no_apps": "Er zijn geen apps ingeschakeld in dit exemplaar van Cal", "no_apps": "Er zijn geen apps ingeschakeld in dit exemplaar van Cal",
"no_apps_configured": "Er is nog geen app geconfigureerd",
"enable_in_settings": "U kunt apps inschakelen in de instellingen",
"please_contact_admin": "Neem contact op met uw beheerder",
"apps_settings": "Appsinstellingen", "apps_settings": "Appsinstellingen",
"fill_this_field": "Vul dit veld in", "fill_this_field": "Vul dit veld in",
"options": "Opties", "options": "Opties",
@@ -1561,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "Weet u zeker dat u de {{connectionType}}-configuratie wilt verwijderen? Uw teamleden die {{connectionType}}-aanmelding gebruiken hebben niet langer toegang tot Cal.com.", "delete_sso_configuration_confirmation_description": "Weet u zeker dat u de {{connectionType}}-configuratie wilt verwijderen? Uw teamleden die {{connectionType}}-aanmelding gebruiken hebben niet langer toegang tot Cal.com.",
"organizer_timezone": "Tijdzone organisator", "organizer_timezone": "Tijdzone organisator",
"email_user_cta": "Uitnodiging weergeven", "email_user_cta": "Uitnodiging weergeven",
"email_no_user_invite_heading": "U bent uitgenodigd om lid te worden van {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn team op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw team in staat stelt vergaderingen te plannen zonder heen en weer te e-mailen.", "email_no_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn team op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw team in staat stelt vergaderingen te plannen zonder heen en weer te e-mailen.",
"email_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn {{entity}} '{{teamName}}' op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw {{entity}} in staat stelt afspraken te plannen zonder heen en weer te e-mailen.",
"email_no_user_invite_steps_intro": "We doorlopen samen een paar korte stappen en in een mum van tijd kunt u genieten van een stressvrije planning met uw {{entity}}.",
"email_no_user_step_one": "Kies uw gebruikersnaam", "email_no_user_step_one": "Kies uw gebruikersnaam",
"email_no_user_step_two": "Koppel uw agenda-account", "email_no_user_step_two": "Koppel uw agenda-account",
"email_no_user_step_three": "Stel uw beschikbaarheid in", "email_no_user_step_three": "Stel uw beschikbaarheid in",
@@ -1572,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "Geen werkstromen", "no_workflows": "Geen werkstromen",
"change_filter": "Wijzig het filter om uw persoonlijke en teamwerkstromen te zien.", "change_filter": "Wijzig het filter om uw persoonlijke en teamwerkstromen te zien.",
"change_filter_common": "Wijzig het filter om de resultaten te zien.",
"no_results_for_filter": "Geen resultaten voor het filter",
"recommended_next_steps": "Aanbevolen volgende stappen", "recommended_next_steps": "Aanbevolen volgende stappen",
"create_a_managed_event": "Maak een beheerd gebeurtenistype", "create_a_managed_event": "Maak een beheerd gebeurtenistype",
"meetings_are_better_with_the_right": "Vergaderingen zijn beter met de juiste teamleden erbij. Nodig ze nu uit.", "meetings_are_better_with_the_right": "Vergaderingen zijn beter met de juiste teamleden erbij. Nodig ze nu uit.",
@@ -1582,7 +1684,9 @@
"no_longer_attending": "U neemt niet langer deel aan deze gebeurtenis", "no_longer_attending": "U neemt niet langer deel aan deze gebeurtenis",
"attendee_no_longer_attending_subject": "Een deelnemer neemt niet langer deel aan {{title}} op {{date}}", "attendee_no_longer_attending_subject": "Een deelnemer neemt niet langer deel aan {{title}} op {{date}}",
"attendee_no_longer_attending": "Een deelnemer neemt niet langer deel aan uw gebeurtenis", "attendee_no_longer_attending": "Een deelnemer neemt niet langer deel aan uw gebeurtenis",
"attendee_no_longer_attending_subtitle": "{{name}} heeft geannuleerd. Dit betekent dat er een plaats is vrijgekomen voor dit tijdslot",
"create_event_on": "Gebeurtenis aanmaken op", "create_event_on": "Gebeurtenis aanmaken op",
"create_routing_form_on": "Maak routeringsformulier op",
"default_app_link_title": "Stel een standaard app-link in", "default_app_link_title": "Stel een standaard app-link in",
"default_app_link_description": "Door een standaard app-link in te stellen kunnen alle nieuw gemaakte gebeurtenistypes de door u ingestelde app-link gebruiken.", "default_app_link_description": "Door een standaard app-link in te stellen kunnen alle nieuw gemaakte gebeurtenistypes de door u ingestelde app-link gebruiken.",
"organizer_default_conferencing_app": "Standaardapp organisator", "organizer_default_conferencing_app": "Standaardapp organisator",
@@ -1592,6 +1696,7 @@
"booking_questions_title": "Boekingsvragen", "booking_questions_title": "Boekingsvragen",
"booking_questions_description": "Pas de gestelde vragen op de boekingspagina aan", "booking_questions_description": "Pas de gestelde vragen op de boekingspagina aan",
"add_a_booking_question": "Vraag toevoegen", "add_a_booking_question": "Vraag toevoegen",
"identifier": "ID",
"duplicate_email": "E-mailadres dubbel", "duplicate_email": "E-mailadres dubbel",
"booking_with_payment_cancelled": "Betalen voor deze gebeurtenis is niet meer mogelijk", "booking_with_payment_cancelled": "Betalen voor deze gebeurtenis is niet meer mogelijk",
"booking_with_payment_cancelled_already_paid": "Een terugbetaling voor deze boeking is onderweg.", "booking_with_payment_cancelled_already_paid": "Een terugbetaling voor deze boeking is onderweg.",
@@ -1602,6 +1707,7 @@
"show_on_booking_page": "Weergeven op boekingspagina", "show_on_booking_page": "Weergeven op boekingspagina",
"get_started_zapier_templates": "Aan de slag met Zapier-sjablonen", "get_started_zapier_templates": "Aan de slag met Zapier-sjablonen",
"team_is_unpublished": "{{team}} is niet gepubliceerd", "team_is_unpublished": "{{team}} is niet gepubliceerd",
"team_is_unpublished_description": "Deze {{entity}}-link is momenteel niet beschikbaar. Neem contact op met de {{entity}}-eigenaar of vraag hem het te publiceren.",
"team_member": "Teamlid", "team_member": "Teamlid",
"a_routing_form": "Een routeringsformulier", "a_routing_form": "Een routeringsformulier",
"form_description_placeholder": "Formulierbeschrijving", "form_description_placeholder": "Formulierbeschrijving",
@@ -1631,13 +1737,16 @@
"spot_popular_event_types": "Spot populaire gebeurtenistypen", "spot_popular_event_types": "Spot populaire gebeurtenistypen",
"spot_popular_event_types_description": "Bekijk welke van uw gebeurtenistypen de meeste kliks en boekingen ontvangen", "spot_popular_event_types_description": "Bekijk welke van uw gebeurtenistypen de meeste kliks en boekingen ontvangen",
"no_responses_yet": "Nog geen reacties", "no_responses_yet": "Nog geen reacties",
"no_routes_defined": "Geen routes bepaald",
"this_will_be_the_placeholder": "Dit wordt de plaatshouder", "this_will_be_the_placeholder": "Dit wordt de plaatshouder",
"error_booking_event": "Er is een fout opgetreden bij het boeken van de gebeurtenis, vernieuw de pagina en probeer het opnieuw",
"timeslot_missing_title": "Geen tijdslot geselecteerd", "timeslot_missing_title": "Geen tijdslot geselecteerd",
"timeslot_missing_description": "Selecteer een tijdslot om de gebeurtenis te boeken.", "timeslot_missing_description": "Selecteer een tijdslot om de gebeurtenis te boeken.",
"timeslot_missing_cta": "Tijdslot selecteren", "timeslot_missing_cta": "Tijdslot selecteren",
"switch_monthly": "Overschakelen naar maandelijkse weergave", "switch_monthly": "Overschakelen naar maandelijkse weergave",
"switch_weekly": "Overschakelen naar wekelijkse weergave", "switch_weekly": "Overschakelen naar wekelijkse weergave",
"switch_multiday": "Overschakelen naar dagelijkse weergave", "switch_multiday": "Overschakelen naar dagelijkse weergave",
"switch_columnview": "Overschakelen naar kolomweergave",
"num_locations": "{{num}} locatieopties", "num_locations": "{{num}} locatieopties",
"select_on_next_step": "Selecteer bij de volgende stap", "select_on_next_step": "Selecteer bij de volgende stap",
"this_meeting_has_not_started_yet": "Deze vergadering is nog niet begonnen", "this_meeting_has_not_started_yet": "Deze vergadering is nog niet begonnen",
@@ -1676,6 +1785,7 @@
"managed_event_dialog_title_one": "De URL /{{slug}} bestaat al voor {{count}} lid. Wilt u deze vervangen?", "managed_event_dialog_title_one": "De URL /{{slug}} bestaat al voor {{count}} lid. Wilt u deze vervangen?",
"managed_event_dialog_title_other": "De URL /{{slug}} bestaat al voor {{count}} leden. Wilt u deze vervangen?", "managed_event_dialog_title_other": "De URL /{{slug}} bestaat al voor {{count}} leden. Wilt u deze vervangen?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> gebruikt de URL <strong>/{{slug}}</strong> al.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> gebruikt de URL <strong>/{{slug}}</strong> al.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> gebruiken de URL <strong>/{{slug}}</strong> al.",
"managed_event_dialog_clarification": "Als u ervoor kiest om de URL te vervangen, informeren wij de leden daarover. Ga terug en verwijder ze als u de URL niet wilt overschrijven.", "managed_event_dialog_clarification": "Als u ervoor kiest om de URL te vervangen, informeren wij de leden daarover. Ga terug en verwijder ze als u de URL niet wilt overschrijven.",
"review_event_type": "Gebeurtenistype bekijken", "review_event_type": "Gebeurtenistype bekijken",
"looking_for_more_analytics": "Op zoek naar meer analyses?", "looking_for_more_analytics": "Op zoek naar meer analyses?",
@@ -1691,12 +1801,14 @@
"least_booked_members": "Minst geboekte leden", "least_booked_members": "Minst geboekte leden",
"events_created": "Gemaakte gebeurtenissen", "events_created": "Gemaakte gebeurtenissen",
"events_completed": "Voltooide gebeurtenissen", "events_completed": "Voltooide gebeurtenissen",
"events_cancelled": "Geannuleerde gebeurtenissen",
"events_rescheduled": "Verplaatste gebeurtenissen", "events_rescheduled": "Verplaatste gebeurtenissen",
"from_last_period": "van afgelopen periode", "from_last_period": "van afgelopen periode",
"from_to_date_period": "Van: {{startDate}} Tot: {{endDate}}", "from_to_date_period": "Van: {{startDate}} Tot: {{endDate}}",
"redirect_url_warning": "Als u een omleiding toevoegt, wordt de succespagina uitgeschakeld. Zorg ervoor dat u op uw aangepaste succespagina \"Boeking bevestigd\" vermeldt.", "redirect_url_warning": "Als u een omleiding toevoegt, wordt de succespagina uitgeschakeld. Zorg ervoor dat u op uw aangepaste succespagina \"Boeking bevestigd\" vermeldt.",
"event_trends": "Gebeurtenistrends", "event_trends": "Gebeurtenistrends",
"clear_filters": "Filters wissen", "clear_filters": "Filters wissen",
"clear": "Wissen",
"hold": "Vasthouden", "hold": "Vasthouden",
"on_booking_option": "Betaling ontvangen bij boeken", "on_booking_option": "Betaling ontvangen bij boeken",
"hold_option": "Afwezigheidsvergoeding in rekening brengen", "hold_option": "Afwezigheidsvergoeding in rekening brengen",
@@ -1723,6 +1835,18 @@
"complete_your_booking": "Voltooi uw boeking", "complete_your_booking": "Voltooi uw boeking",
"complete_your_booking_subject": "Voltooi uw boeking: {{title}} op {{date}}", "complete_your_booking_subject": "Voltooi uw boeking: {{title}} op {{date}}",
"confirm_your_details": "Bevestig uw gegevens", "confirm_your_details": "Bevestig uw gegevens",
"copy_invite_link": "Uitnodigingslink kopiëren",
"edit_invite_link": "Linkinstellingen bewerken",
"invite_link_copied": "Uitnodigingslink gekopieerd",
"invite_link_deleted": "Uitnodigingslink verwijderd",
"invite_link_updated": "Uitnodigingslinkinstellingen opgeslagen",
"link_expires_after": "Links verlopen na...",
"one_day": "1 dag",
"seven_days": "7 dagen",
"thirty_days": "30 dagen",
"three_months": "3 maanden",
"one_year": "1 jaar",
"team_invite_received": "U bent uitgenodigd om lid te worden van {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "U staat op het punt om de deelnemer {{amount, currency}} in rekening te brengen. Weet u zeker dat u wilt doorgaan?", "charge_card_dialog_body": "U staat op het punt om de deelnemer {{amount, currency}} in rekening te brengen. Weet u zeker dat u wilt doorgaan?",
"charge_attendee": "Deelnemer {{amount, currency}} in rekening brengen", "charge_attendee": "Deelnemer {{amount, currency}} in rekening brengen",
@@ -1731,6 +1855,7 @@
"email_invite_team_bulk": "{{userCount}} gebruikers zijn uitgenodigd", "email_invite_team_bulk": "{{userCount}} gebruikers zijn uitgenodigd",
"error_collecting_card": "Fout bij incasseren van kaart", "error_collecting_card": "Fout bij incasseren van kaart",
"image_size_limit_exceed": "De geüploade afbeelding mag niet groter zijn dan 5 MB", "image_size_limit_exceed": "De geüploade afbeelding mag niet groter zijn dan 5 MB",
"unauthorized_workflow_error_message": "{{errorCode}}: u bent niet geautoriseerd om deze werkstroom in of uit te schakelen",
"inline_embed": "Inline insluiting", "inline_embed": "Inline insluiting",
"load_inline_content": "Laadt uw gebeurtenistype rechtstreeks inline met uw andere websitecontent.", "load_inline_content": "Laadt uw gebeurtenistype rechtstreeks inline met uw andere websitecontent.",
"floating_pop_up_button": "Zwevende pop-upknop", "floating_pop_up_button": "Zwevende pop-upknop",
@@ -1750,6 +1875,69 @@
"connect_google_workspace": "Google Workspace koppelen", "connect_google_workspace": "Google Workspace koppelen",
"google_workspace_admin_tooltip": "U moet een Google Workspace-beheerder zijn om deze functie te gebruiken", "google_workspace_admin_tooltip": "U moet een Google Workspace-beheerder zijn om deze functie te gebruiken",
"first_event_type_webhook_description": "Maak uw eerste webhook voor dit gebeurtenistype", "first_event_type_webhook_description": "Maak uw eerste webhook voor dit gebeurtenistype",
"install_app_on": "Installeer app op",
"create_for": "Maken voor", "create_for": "Maken voor",
"insights_all_org_filter": "Alle apps" "setup_organization": "Stel een organisatie in",
"organization_banner_description": "Maak een omgeving waarin uw teams gedeelde apps, werkstromen en gebeurtenistypen kunnen maken met round-robin en collectieve planning.",
"organization_banner_title": "Beheer organisaties met meerdere teams",
"set_up_your_organization": "Stel uw organisatie in",
"organizations_description": "Organisaties zijn gedeelde omgevingen waar teams gedeelde gebeurtenistypen, apps, werkstromen en meer kunnen maken.",
"must_enter_organization_name": "U moet een organisatienaam invoeren",
"must_enter_organization_admin_email": "U moet het e-mailadres van uw organisatie invoeren",
"admin_email": "E-mailadres van uw organisatie",
"admin_username": "Gebruikersnaam beheerder",
"organization_name": "Organisatienaam",
"organization_url": "Organisatie-URL",
"organization_verify_header": "Verifieer het e-mailadres van uw organisatie",
"organization_verify_email_body": "Gebruik de onderstaande code om uw e-mailadres te verifiëren en door te gaan met het instellen van uw organisatie.",
"additional_url_parameters": "Extra URL-parameters",
"about_your_organization": "Over uw organisatie",
"about_your_organization_description": "Organisaties zijn gedeelde omgevingen waar u meerdere teams met gedeelde gebeurtenistypen, apps, werkstromen en meer kunt maken.",
"create_your_teams": "Maak uw teams",
"create_your_teams_description": "Begin met samen plannen door uw teamleden aan uw organisatie toe te voegen",
"invite_organization_admins": "Nodig uw organisatiebeheerders uit",
"invite_organization_admins_description": "Deze beheerders hebben toegang tot alle teams in uw organisatie. U kunt later teambeheerders en -leden toevoegen.",
"set_a_password": "Stel een wachtwoord in",
"set_a_password_description": "Hierdoor wordt een nieuwe gebruikersaccount gemaakt met het e-mailadres van uw organisatie en dit wachtwoord.",
"organization_logo": "Organisatielogo",
"organization_about_description": "Een paar zinnen over uw organisatie. Dit wordt weergegeven op de openbare profielpagina van uw organisatie.",
"ill_do_this_later": "Ik doe dit later",
"verify_your_email": "Verifieer uw e-mailadres",
"enter_digit_code": "Voer de 6-cijferige code in die we naar {{email}} hebben gestuurd",
"verify_email_organization": "Verifieer uw e-mailadres om een organisatie te maken",
"code_provided_invalid": "De opgegeven code is ongeldig, probeer het opnieuw",
"email_already_used": "Het e-mailadres wordt al gebruikt",
"organization_admin_invited_heading": "U bent uitgenodigd om lid te worden van {{orgName}}",
"organization_admin_invited_body": "Word lid van uw team bij {{orgName}} en begin u met het richten op afspraken, niet op het maken van afspraken!",
"duplicated_slugs_warning": "De volgende teams konden niet worden gemaakt vanwege dubbele slugs: {{slugs}}",
"team_names_empty": "Teamnamen mogen niet leeg zijn",
"team_names_repeated": "Teamnamen mogen niet herhaald worden",
"user_belongs_organization": "Gebruiker behoort tot een organisatie",
"org_no_teams_yet": "Deze organisatie heeft nog geen teams",
"org_no_teams_yet_description": "Als u een beheerder bent, zorg er dan voor dat u teams maakt die hier weergegeven worden.",
"set_up": "Instellen",
"set_up_your_profile": "Stel uw profiel in",
"set_up_your_profile_description": "Laat mensen weten wie u bent binnen {{orgName}} en wanneer ze uw openbare link gebruiken.",
"my_profile": "Mijn profiel",
"my_settings": "Mijn instellingen",
"crm": "CRM",
"messaging": "Berichten",
"sender_id_info": "Naam of nummer weergegeven als de afzender van een sms (sommige landen staan geen alfanumerieke afzender-ID's toe)",
"org_admins_can_create_new_teams": "Alleen de beheerder van uw organisatie kan nieuwe teams maken",
"google_new_spam_policy": "Het nieuwe spambeleid van Google kan ervoor zorgen dat u geen e-mail- en agendameldingen over deze boeking ontvangt.",
"resolve": "Oplossen",
"no_organization_slug": "Er is een fout opgetreden bij het maken van teams voor deze organisatie. Ontbrekende URL-slug.",
"org_name": "Organisatienaam",
"org_url": "Organisatie-URL",
"copy_link_org": "Kopieer link naar organisatie",
"404_the_org": "De organisatie",
"404_the_team": "Het team",
"404_claim_entity_org": "Claim uw subdomein voor uw organisatie",
"404_claim_entity_team": "Claim dit team en begin met het gezamenlijk beheren van planningen",
"insights_all_org_filter": "Alle apps",
"insights_team_filter": "Team: {{teamName}}",
"insights_user_filter": "Gebruiker: {{userName}}",
"insights_subtitle": "Bekijk boekingsinsights voor al uw gebeurtenissen",
"custom_plan": "Aangepast abonnement",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Voeg uw nieuwe strings hierboven toe ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+95 -8
View File
@@ -11,12 +11,15 @@
"calcom_explained_new_user": "Dokończ konfigurację konta aplikacji {{appName}}! Od rozwiązania wszystkich Twoich problemów z układaniem grafików dzieli Cię tylko kilka kroków.", "calcom_explained_new_user": "Dokończ konfigurację konta aplikacji {{appName}}! Od rozwiązania wszystkich Twoich problemów z układaniem grafików dzieli Cię tylko kilka kroków.",
"have_any_questions": "Masz pytania? Jesteśmy tutaj, aby pomóc.", "have_any_questions": "Masz pytania? Jesteśmy tutaj, aby pomóc.",
"reset_password_subject": "{{appName}}: Instrukcje resetowania hasła", "reset_password_subject": "{{appName}}: Instrukcje resetowania hasła",
"verify_email_subject": "{{appName}}: Zweryfikuj swoje konto", "verify_email_subject": "{{appName}}: zweryfikuj swoje konto",
"check_your_email": "Sprawdź swój e-mail", "check_your_email": "Sprawdź adres e-mail",
"verify_email_page_body": "Wysłaliśmy wiadomość e-mail na adres {{email}}. Weryfikacja adresu e-mail jest bardzo ważna, ponieważ umożliwia upewnienie się, czy kalendarz i wiadomości e-mail z aplikacji {{appName}} będą działać prawidłowo.", "verify_email_page_body": "Wysłaliśmy wiadomość e-mail na adres {{email}}. Weryfikacja adresu e-mail jest bardzo ważna, ponieważ umożliwia upewnienie się, czy kalendarz i wiadomości e-mail z aplikacji {{appName}} będą działać prawidłowo.",
"verify_email_banner_body": "Zweryfikuj adres email, aby upewnić się, że wiadomości e-mail i powiadomienia z kalendarza będą do Ciebie docierać.", "verify_email_banner_body": "Potwierdź adres email, aby upewnić się, że wiadomości e-mail i powiadomienia z kalendarza będą do Ciebie docierać.",
"verify_email_email_header": "Zweryfikuj adres e-mail", "verify_email_email_header": "Zweryfikuj adres e-mail",
"verify_email_email_button": "Potwierdź e-mail", "verify_email_email_button": "Potwierdź adres e-mail",
"verify_email_email_body": "Potwierdź adres e-mail poprzez kliknięcie poniższego przycisku.",
"verify_email_email_link_text": "Oto link, jeśli nie lubisz klikać przycisków:",
"email_sent": "Wysłano wiadomość e-mail",
"event_declined_subject": "Odrzucono: {{title}} w dniu {{date}}", "event_declined_subject": "Odrzucono: {{title}} w dniu {{date}}",
"event_cancelled_subject": "Anulowano: {{title}}, {{date}}", "event_cancelled_subject": "Anulowano: {{title}}, {{date}}",
"event_request_declined": "Twoja prośba o wydarzenie została odrzucona", "event_request_declined": "Twoja prośba o wydarzenie została odrzucona",
@@ -312,6 +315,7 @@
"bookerlayout_error_min_one_enabled": "Trzeba włączyć co najmniej jeden układ.", "bookerlayout_error_min_one_enabled": "Trzeba włączyć co najmniej jeden układ.",
"bookerlayout_error_default_not_enabled": "Układ wybrany jako widok domyślny nie jest częścią włączonych układów.", "bookerlayout_error_default_not_enabled": "Układ wybrany jako widok domyślny nie jest częścią włączonych układów.",
"bookerlayout_error_unknown_layout": "Wybrany układ nie jest prawidłowym układem.", "bookerlayout_error_unknown_layout": "Wybrany układ nie jest prawidłowym układem.",
"bookerlayout_override_global_settings": "Możesz zarządzać tym ustawieniem w odniesieniu do wszystkich typów wydarzeń w sekcji <2>Ustawienia / Wygląd</2> lub <6>zastąpić je tylko w przypadku tego wydarzenia</6>.",
"unexpected_error_try_again": "Wystąpił nieoczekiwany błąd. Spróbuj ponownie.", "unexpected_error_try_again": "Wystąpił nieoczekiwany błąd. Spróbuj ponownie.",
"sunday_time_error": "Nieprawidłowy czas na niedzielę", "sunday_time_error": "Nieprawidłowy czas na niedzielę",
"monday_time_error": "Nieprawidłowy czas na poniedziałek", "monday_time_error": "Nieprawidłowy czas na poniedziałek",
@@ -348,7 +352,7 @@
"no_status_bookings_yet_description": "Nie masz {{status}} rezerwacji. {{description}}", "no_status_bookings_yet_description": "Nie masz {{status}} rezerwacji. {{description}}",
"event_between_users": "{{eventName}} między {{host}} a {{attendeeName}}", "event_between_users": "{{eventName}} między {{host}} a {{attendeeName}}",
"bookings": "Rezerwacje", "bookings": "Rezerwacje",
"booking_not_found": "Rezerwacja nie została znaleziona", "booking_not_found": "Rezerwacja nie została znaleziona.",
"bookings_description": "Zobacz nadchodzące i przeszłe wydarzenia zarezerwowane za pomocą linków tego wydarzenia.", "bookings_description": "Zobacz nadchodzące i przeszłe wydarzenia zarezerwowane za pomocą linków tego wydarzenia.",
"upcoming_bookings": "Jak tylko ktoś zarezerwuje czas z Tobą, to pojawi się tutaj.", "upcoming_bookings": "Jak tylko ktoś zarezerwuje czas z Tobą, to pojawi się tutaj.",
"recurring_bookings": "Jak tylko ktoś zarezerwuje cykliczne spotkanie z Tobą, to pojawi się ono tutaj.", "recurring_bookings": "Jak tylko ktoś zarezerwuje cykliczne spotkanie z Tobą, to pojawi się ono tutaj.",
@@ -1075,7 +1079,7 @@
"url_start_with_https": "Adres URL musi zaczynać się od http:// lub https://", "url_start_with_https": "Adres URL musi zaczynać się od http:// lub https://",
"number_provided": "Numer telefonu zostanie podany.", "number_provided": "Numer telefonu zostanie podany.",
"before_event_trigger": "przed rozpoczęciem wydarzenia", "before_event_trigger": "przed rozpoczęciem wydarzenia",
"event_cancelled_trigger": "gdy wydarzenie zostanie odwołane", "event_cancelled_trigger": "gdy wydarzenie zostanie anulowane",
"new_event_trigger": "gdy nowe wydarzenie zostanie zarezerwowane", "new_event_trigger": "gdy nowe wydarzenie zostanie zarezerwowane",
"email_host_action": "wyślij wiadomość e-mail do hosta", "email_host_action": "wyślij wiadomość e-mail do hosta",
"email_attendee_action": "wyślij wiadomość e-mail do uczestników", "email_attendee_action": "wyślij wiadomość e-mail do uczestników",
@@ -1479,7 +1483,7 @@
"yearly": "Co rok", "yearly": "Co rok",
"checkout": "Do kasy", "checkout": "Do kasy",
"your_team_disbanded_successfully": "Twój zespół został rozwiązany.", "your_team_disbanded_successfully": "Twój zespół został rozwiązany.",
"your_org_disbanded_successfully": "Twoja organizacja została rozwiązany.", "your_org_disbanded_successfully": "Twoja organizacja została rozwiązana.",
"error_creating_team": "Podczas tworzenia zespołu wystąpił błąd", "error_creating_team": "Podczas tworzenia zespołu wystąpił błąd",
"you": "Ty", "you": "Ty",
"resend_email": "Wyślij wiadomość e-mail ponownie", "resend_email": "Wyślij wiadomość e-mail ponownie",
@@ -1703,6 +1707,7 @@
"show_on_booking_page": "Pokaż na stronie rezerwacji", "show_on_booking_page": "Pokaż na stronie rezerwacji",
"get_started_zapier_templates": "Zacznij korzystać z szablonów Zapier", "get_started_zapier_templates": "Zacznij korzystać z szablonów Zapier",
"team_is_unpublished": "Zespół {{team}} nie został opublikowany", "team_is_unpublished": "Zespół {{team}} nie został opublikowany",
"team_is_unpublished_description": "Link jednostki {{entity}} jest obecnie niedostępny. Skontaktuj się z właścicielem jednostki {{entity}} lub poproś o jego opublikowanie.",
"team_member": "Członek zespołu", "team_member": "Członek zespołu",
"a_routing_form": "Formularz przekierowania", "a_routing_form": "Formularz przekierowania",
"form_description_placeholder": "Opis formularza", "form_description_placeholder": "Opis formularza",
@@ -1732,13 +1737,16 @@
"spot_popular_event_types": "Przekonaj się, które typy wydarzeń są popularne", "spot_popular_event_types": "Przekonaj się, które typy wydarzeń są popularne",
"spot_popular_event_types_description": "Zobacz, które typy wydarzeń są najczęściej klikane i rezerwowane", "spot_popular_event_types_description": "Zobacz, które typy wydarzeń są najczęściej klikane i rezerwowane",
"no_responses_yet": "Nie ma jeszcze odpowiedzi", "no_responses_yet": "Nie ma jeszcze odpowiedzi",
"no_routes_defined": "Brak zdefiniowanych przekierowań",
"this_will_be_the_placeholder": "To będzie symbol zastępczy", "this_will_be_the_placeholder": "To będzie symbol zastępczy",
"error_booking_event": "Podczas rezerwacji wydarzenia wystąpił błąd, odśwież stronę i spróbuj ponownie.",
"timeslot_missing_title": "Nie wybrano przedziału czasowego", "timeslot_missing_title": "Nie wybrano przedziału czasowego",
"timeslot_missing_description": "Wybierz przedział czasowy, aby zarezerwować wydarzenie.", "timeslot_missing_description": "Wybierz przedział czasowy, aby zarezerwować wydarzenie.",
"timeslot_missing_cta": "Wybierz przedział czasowy", "timeslot_missing_cta": "Wybierz przedział czasowy",
"switch_monthly": "Przełącz na widok miesiąca", "switch_monthly": "Przełącz na widok miesiąca",
"switch_weekly": "Przełącz na widok tygodnia", "switch_weekly": "Przełącz na widok tygodnia",
"switch_multiday": "Przełącz na widok dnia", "switch_multiday": "Przełącz na widok dnia",
"switch_columnview": "Przełącz na widok kolumny",
"num_locations": "Lokalizacje do wyboru: {{num}}", "num_locations": "Lokalizacje do wyboru: {{num}}",
"select_on_next_step": "Wybierz następny krok", "select_on_next_step": "Wybierz następny krok",
"this_meeting_has_not_started_yet": "To spotkanie jeszcze się nie rozpoczęło", "this_meeting_has_not_started_yet": "To spotkanie jeszcze się nie rozpoczęło",
@@ -1777,6 +1785,7 @@
"managed_event_dialog_title_one": "Adres URL /{{slug}} już istnieje dla {{count}} członka. Czy chcesz go zastąpić?", "managed_event_dialog_title_one": "Adres URL /{{slug}} już istnieje dla {{count}} członka. Czy chcesz go zastąpić?",
"managed_event_dialog_title_other": "Adres URL /{{slug}} już istnieje dla {{count}} członków. Czy chcesz go zastąpić?", "managed_event_dialog_title_other": "Adres URL /{{slug}} już istnieje dla {{count}} członków. Czy chcesz go zastąpić?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> używa już adresu URL <strong>/{{slug}}</strong>.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> używa już adresu URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> używają już adresu URL <strong>/{{slug}}</strong>.",
"managed_event_dialog_clarification": "Jeśli zdecydujesz się go zastąpić, powiadomimy te osoby. Wróć i usuń je, jeśli nie chcesz zastępować adresu.", "managed_event_dialog_clarification": "Jeśli zdecydujesz się go zastąpić, powiadomimy te osoby. Wróć i usuń je, jeśli nie chcesz zastępować adresu.",
"review_event_type": "Sprawdź typ wydarzenia", "review_event_type": "Sprawdź typ wydarzenia",
"looking_for_more_analytics": "Szukasz dokładniejszych danych analitycznych?", "looking_for_more_analytics": "Szukasz dokładniejszych danych analitycznych?",
@@ -1792,12 +1801,14 @@
"least_booked_members": "Najrzadziej rezerwowani członkowie", "least_booked_members": "Najrzadziej rezerwowani członkowie",
"events_created": "Utworzone wydarzenia", "events_created": "Utworzone wydarzenia",
"events_completed": "Ukończone wydarzenia", "events_completed": "Ukończone wydarzenia",
"events_cancelled": "Anulowane wydarzenia",
"events_rescheduled": "Przełożone wydarzenia", "events_rescheduled": "Przełożone wydarzenia",
"from_last_period": "od ostatniego okresu", "from_last_period": "od ostatniego okresu",
"from_to_date_period": "Od: {{startDate}} Do: {{endDate}}", "from_to_date_period": "Od: {{startDate}} Do: {{endDate}}",
"redirect_url_warning": "Dodanie przekierowania wyłączy stronę powodzenia. Upewnij się, że na Twojej niestandardowej stronie powodzenia znajduje się wzmianka o potwierdzeniu rezerwacji.", "redirect_url_warning": "Dodanie przekierowania wyłączy stronę powodzenia. Upewnij się, że na Twojej niestandardowej stronie powodzenia znajduje się wzmianka o potwierdzeniu rezerwacji.",
"event_trends": "Trendy wydarzeń", "event_trends": "Trendy wydarzeń",
"clear_filters": "Wyczyść filtry", "clear_filters": "Wyczyść filtry",
"clear": "Wyczyść",
"hold": "Zablokowano", "hold": "Zablokowano",
"on_booking_option": "Pobierz płatność przy rezerwacji", "on_booking_option": "Pobierz płatność przy rezerwacji",
"hold_option": "Pobierz opłatę za niestawienie się", "hold_option": "Pobierz opłatę za niestawienie się",
@@ -1824,6 +1835,18 @@
"complete_your_booking": "Ukończ rezerwację", "complete_your_booking": "Ukończ rezerwację",
"complete_your_booking_subject": "Ukończ rezerwację: {{title}} dnia {{date}}", "complete_your_booking_subject": "Ukończ rezerwację: {{title}} dnia {{date}}",
"confirm_your_details": "Potwierdź swoje dane", "confirm_your_details": "Potwierdź swoje dane",
"copy_invite_link": "Skopij link zaproszenia",
"edit_invite_link": "Edytuj ustawienia linku",
"invite_link_copied": "Skopiowano link zaproszenia",
"invite_link_deleted": "Usunięto link zaproszenia",
"invite_link_updated": "Zapisano ustawienia linku zaproszenia",
"link_expires_after": "Linki wygasną po upływie...",
"one_day": "1 dnia",
"seven_days": "7 dni",
"thirty_days": "30 dni",
"three_months": "3 miesięcy",
"one_year": "roku",
"team_invite_received": "Zaproszono Cię do zespołu {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Zamierzasz obciążyć uczestnika kwotą {{amount, currency}}. Czy na pewno chcesz kontynuować?", "charge_card_dialog_body": "Zamierzasz obciążyć uczestnika kwotą {{amount, currency}}. Czy na pewno chcesz kontynuować?",
"charge_attendee": "Obciąż uczestnika kwotą {{amount, currency}}", "charge_attendee": "Obciąż uczestnika kwotą {{amount, currency}}",
@@ -1832,6 +1855,7 @@
"email_invite_team_bulk": "Zaproszono {{userCount}} użytkowników", "email_invite_team_bulk": "Zaproszono {{userCount}} użytkowników",
"error_collecting_card": "Błąd podczas pobierania należności z karty", "error_collecting_card": "Błąd podczas pobierania należności z karty",
"image_size_limit_exceed": "Rozmiar przesyłanego obrazu nie powinien przekraczać limitu 5 MB", "image_size_limit_exceed": "Rozmiar przesyłanego obrazu nie powinien przekraczać limitu 5 MB",
"unauthorized_workflow_error_message": "{{errorCode}}: nie masz uprawnień do włączenia lub wyłączenia tego przepływu pracy.",
"inline_embed": "Osadź w stronie", "inline_embed": "Osadź w stronie",
"load_inline_content": "Wczytuje typ wydarzenia bezpośrednio w treści Twojej strony internetowej.", "load_inline_content": "Wczytuje typ wydarzenia bezpośrednio w treści Twojej strony internetowej.",
"floating_pop_up_button": "Pływający przycisk wyskakujący", "floating_pop_up_button": "Pływający przycisk wyskakujący",
@@ -1851,6 +1875,69 @@
"connect_google_workspace": "Podłącz usługę Google Workspace", "connect_google_workspace": "Podłącz usługę Google Workspace",
"google_workspace_admin_tooltip": "Aby skorzystać z tej funkcji, musisz być administratorem usługi Workspace.", "google_workspace_admin_tooltip": "Aby skorzystać z tej funkcji, musisz być administratorem usługi Workspace.",
"first_event_type_webhook_description": "Utwórz swój pierwszy element webhook dla tego typu wydarzenia", "first_event_type_webhook_description": "Utwórz swój pierwszy element webhook dla tego typu wydarzenia",
"install_app_on": "Zainstaluj aplikację na:",
"create_for": "Utwórz dla", "create_for": "Utwórz dla",
"insights_all_org_filter": "Wszystkie" "setup_organization": "Skonfiguruj organizację",
"organization_banner_description": "Utwórz środowisko, w którym zespoły będą mogły dzielić się aplikacjami, przepływami pracy i typami wydarzeń przy użyciu algorytmu karuzelowego lub zbiorowego ustalania harmonogramu.",
"organization_banner_title": "Zarządzaj organizacjami z wieloma zespołami",
"set_up_your_organization": "Skonfiguruj organizację",
"organizations_description": "Organizacje to współdzielone środowiska, w których zespoły mogą tworzyć wspólne typy wydarzeń, aplikacje, przepływy pracy i nie tylko.",
"must_enter_organization_name": "Nazwa organizacji jest wymagana.",
"must_enter_organization_admin_email": "Adres e-mail organizacji jest wymagany.",
"admin_email": "Adres e-mail organizacji",
"admin_username": "Nazwa użytkownika administratora",
"organization_name": "Nazwa organizacji",
"organization_url": "Adres URL organizacji",
"organization_verify_header": "Zweryfikuj adres e-mail organizacji",
"organization_verify_email_body": "Użyj poniższego kodu, aby zweryfikować adres e-mail i kontynuować konfigurację organizacji.",
"additional_url_parameters": "Dodatkowe parametry adresu URL",
"about_your_organization": "Informacje o Twojej organizacji",
"about_your_organization_description": "Organizacje to współdzielone środowiska, w których możesz utworzyć wiele zespołów ze wspólnymi członkami, typami wydarzeń, aplikacjami, przepływami pracy i nie tylko.",
"create_your_teams": "Utwórz zespoły",
"create_your_teams_description": "Zacznij wspólne planowanie poprzez dodanie członków zespołu do Twojej organizacji",
"invite_organization_admins": "Zaproś administratorów organizacji",
"invite_organization_admins_description": "Administratorzy będą mieli dostęp do wszystkich zespołów w Twojej organizacji. Administratorów i członków zespołu możesz dodać później.",
"set_a_password": "Ustaw hasło",
"set_a_password_description": "Spowoduje to utworzenie nowego konta użytkownika z adresem e-mail Twojej organizacji i wybranym hasłem.",
"organization_logo": "Logo organizacji",
"organization_about_description": "Kilka zdań na temat Twojej organizacji. Pojawią się na publicznej stronie profilowej Twojej organizacji.",
"ill_do_this_later": "Zrobię to później",
"verify_your_email": "Potwierdź adres e-mail",
"enter_digit_code": "Wprowadź 6-cyfrowy kod, który wysłaliśmy na adres {{email}}",
"verify_email_organization": "Potwierdź adres e-mail, aby utworzyć organizację",
"code_provided_invalid": "Podany kod jest nieprawidłowy, spróbuj ponownie.",
"email_already_used": "Adres e-mail jest już używany.",
"organization_admin_invited_heading": "Zaproszono Cię do organizacji {{orgName}}",
"organization_admin_invited_body": "Dołącz do Twojego zespołu w organizacji {{orgName}} i zacznij skupiać się na spotkaniu, a nie jego umawianiu!",
"duplicated_slugs_warning": "Następujące zespoły nie mogły zostać utworzone z powodu zduplikowanych slugów: {{slugs}}",
"team_names_empty": "Nazwy zespołów nie mogą być puste.",
"team_names_repeated": "Nazwy zespołów nie mogą się powtarzać.",
"user_belongs_organization": "Użytkownik należy do organizacji.",
"org_no_teams_yet": "W tej organizacji nie ma jeszcze żadnych zespołów.",
"org_no_teams_yet_description": "Jeśli jesteś administratorem, pamiętaj o utworzeniu zespołów, które będą wyświetlane tutaj.",
"set_up": "Skonfiguruj",
"set_up_your_profile": "Skonfiguruj profil",
"set_up_your_profile_description": "Określ, jakie informacje o Twojej roli w organizacji {{orgName}} zobaczą osoby, które klikną Twój link publiczny.",
"my_profile": "Mój profil",
"my_settings": "Moje ustawienia",
"crm": "CRM",
"messaging": "Wiadomości",
"sender_id_info": "Nazwa lub numer wyświetlany jako nadawca wiadomości SMS (niektóre kraje nie zezwalają na alfanumeryczne identyfikatory nadawcy)",
"org_admins_can_create_new_teams": "Tylko administrator Twojej organizacji może tworzyć nowe zespoły.",
"google_new_spam_policy": "Nowa polityka firmy Google dotycząca spamu może uniemożliwić Ci otrzymywanie powiadomień e-mail i kalendarza na temat tej rezerwacji.",
"resolve": "Rozwiąż",
"no_organization_slug": "Podczas tworzenia zespołów tej organizacji wystąpił błąd. Brakujący slug adresu URL.",
"org_name": "Nazwa organizacji",
"org_url": "Adres URL organizacji",
"copy_link_org": "Skopiuj link do organizacji",
"404_the_org": "Organizacja",
"404_the_team": "Zespół",
"404_claim_entity_org": "Zajmij subdomenę dla Twojej organizacji",
"404_claim_entity_team": "Zajmij ten zespół i zacznij wspólnie zarządzać harmonogramami",
"insights_all_org_filter": "Wszystkie",
"insights_team_filter": "Zespół: {{teamName}}",
"insights_user_filter": "Użytkownik: {{userName}}",
"insights_subtitle": "Wyświetl wskaźniki rezerwacji z różnych wydarzeń",
"custom_plan": "Plan niestandardowy",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Dodaj nowe ciągi powyżej ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -1306,6 +1306,7 @@
"connect_other_apps": "Conectar outros aplicativos", "connect_other_apps": "Conectar outros aplicativos",
"connect_web3_apps": "Conecte aplicativos web3", "connect_web3_apps": "Conecte aplicativos web3",
"connect_messaging_apps": "Conectar com aplicativos de mensagem", "connect_messaging_apps": "Conectar com aplicativos de mensagem",
"connect_crm_apps": "Conecte aplicativos CRM",
"current_step_of_total": "Passo {{currentStep}} de {{maxSteps}}", "current_step_of_total": "Passo {{currentStep}} de {{maxSteps}}",
"add_variable": "Adicionar variável", "add_variable": "Adicionar variável",
"custom_phone_number": "Número de telefone personalizado", "custom_phone_number": "Número de telefone personalizado",
@@ -1318,12 +1319,14 @@
"location_info": "O local do evento", "location_info": "O local do evento",
"additional_notes_info": "Notas adicionais da reserva", "additional_notes_info": "Notas adicionais da reserva",
"attendee_name_info": "O nome da pessoa que fez a reserva", "attendee_name_info": "O nome da pessoa que fez a reserva",
"organizer_name_info": "Nome do organizador",
"to": "Para", "to": "Para",
"workflow_turned_on_successfully": "Fluxo de trabalho {{workflowName}} atualizado para {{offOn}} com sucesso", "workflow_turned_on_successfully": "Fluxo de trabalho {{workflowName}} atualizado para {{offOn}} com sucesso",
"download_responses": "Baixar respostas", "download_responses": "Baixar respostas",
"download_responses_description": "Baixe todas as respostas para seu formulário em formato CSV.", "download_responses_description": "Baixe todas as respostas para seu formulário em formato CSV.",
"download": "Baixar", "download": "Baixar",
"download_recording": "Baixar gravação", "download_recording": "Baixar gravação",
"recording_from_your_recent_call": "Uma gravação da sua chamada recente no {{appName}} está pronta para ser baixada",
"create_your_first_form": "Criar seu primeiro formulário", "create_your_first_form": "Criar seu primeiro formulário",
"create_your_first_form_description": "Com os Formulários de roteamento, você pode fazer perguntas e encaminhar para a pessoa correta ou o tipo de evento.", "create_your_first_form_description": "Com os Formulários de roteamento, você pode fazer perguntas e encaminhar para a pessoa correta ou o tipo de evento.",
"create_your_first_webhook": "Criar seu primeiro Webhook", "create_your_first_webhook": "Criar seu primeiro Webhook",
@@ -1332,7 +1335,9 @@
"event_one": "evento", "event_one": "evento",
"event_other": "eventos", "event_other": "eventos",
"profile_team_description": "Gerenciar as configurações para o perfil da sua equipe", "profile_team_description": "Gerenciar as configurações para o perfil da sua equipe",
"profile_org_description": "Gerencie as configurações para o perfil da sua organização",
"members_team_description": "Usuários que estão no grupo", "members_team_description": "Usuários que estão no grupo",
"organization_description": "Gerencie os administradores e membros da sua organização",
"team_url": "URL da equipe", "team_url": "URL da equipe",
"team_members": "Membros da equipe", "team_members": "Membros da equipe",
"more": "Mais", "more": "Mais",
@@ -1373,6 +1378,7 @@
"routing_forms_send_email_owner": "Enviar e-mail ao proprietário", "routing_forms_send_email_owner": "Enviar e-mail ao proprietário",
"routing_forms_send_email_owner_description": "Envia um e-mail ao proprietário após o envio do formulário", "routing_forms_send_email_owner_description": "Envia um e-mail ao proprietário após o envio do formulário",
"add_new_form": "Adicionar novo formulário", "add_new_form": "Adicionar novo formulário",
"add_new_team_form": "Adicionar novo formulário à sua equipe",
"create_your_first_route": "Crie sua primeira rota", "create_your_first_route": "Crie sua primeira rota",
"route_to_the_right_person": "Roteie para a pessoa certa com base nas respostas do seu formulário", "route_to_the_right_person": "Roteie para a pessoa certa com base nas respostas do seu formulário",
"form_description": "Crie o seu formulário para encaminhar um reservante", "form_description": "Crie o seu formulário para encaminhar um reservante",
@@ -1458,6 +1464,7 @@
"new_event_type_availability": "Disponibilidade de {{eventTypeTitle}}", "new_event_type_availability": "Disponibilidade de {{eventTypeTitle}}",
"error_editing_availability": "Erro ao editar disponibilidade", "error_editing_availability": "Erro ao editar disponibilidade",
"dont_have_permission": "Você não tem permissão para acessar este recurso.", "dont_have_permission": "Você não tem permissão para acessar este recurso.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Por favor cole o SAML metadata do seu Provedor de Identidade aqui", "saml_configuration_placeholder": "Por favor cole o SAML metadata do seu Provedor de Identidade aqui",
"saml_email_required": "Por favor insira um endereço de e-mail para que possamos encontrar o seu Provedor de Identidade", "saml_email_required": "Por favor insira um endereço de e-mail para que possamos encontrar o seu Provedor de Identidade",
"saml_sp_title": "Detalhes do Provedor de Serviços", "saml_sp_title": "Detalhes do Provedor de Serviços",
@@ -1476,15 +1483,19 @@
"yearly": "Anual", "yearly": "Anual",
"checkout": "Finalizar compra", "checkout": "Finalizar compra",
"your_team_disbanded_successfully": "Sua equipe foi desfeita com êxito", "your_team_disbanded_successfully": "Sua equipe foi desfeita com êxito",
"your_org_disbanded_successfully": "Sua organização foi desfeita com êxito",
"error_creating_team": "Erro ao criar equipe", "error_creating_team": "Erro ao criar equipe",
"you": "Você", "you": "Você",
"resend_email": "Reenviar e-mail",
"member_already_invited": "O membro já foi convidado", "member_already_invited": "O membro já foi convidado",
"enter_email_or_username": "Insira um e-mail ou nome de usuário", "enter_email_or_username": "Insira um e-mail ou nome de usuário",
"team_name_taken": "Este nome já está em uso", "team_name_taken": "Este nome já está em uso",
"must_enter_team_name": "É preciso inserir um nome de equipe", "must_enter_team_name": "É preciso inserir um nome de equipe",
"team_url_required": "É preciso inserir uma URL de equipe", "team_url_required": "É preciso inserir uma URL de equipe",
"url_taken": "Este URL já está em uso", "url_taken": "Este URL já está em uso",
"problem_registering_domain": "Houve um problema ao registrar o subdomínio, tente novamente ou fale com o administrador",
"team_publish": "Publicar equipe", "team_publish": "Publicar equipe",
"number_text_notifications": "Número de telefone (notificações via texto)",
"attendee_email_variable": "E-mail do participante", "attendee_email_variable": "E-mail do participante",
"attendee_email_info": "O e-mail da pessoa que fez a reserva", "attendee_email_info": "O e-mail da pessoa que fez a reserva",
"kbar_search_placeholder": "Digite um comando ou procure...", "kbar_search_placeholder": "Digite um comando ou procure...",
@@ -1507,6 +1518,8 @@
"find_the_best_person": "Encontre a pessoa mais indicada disponível e percorra sua equipe.", "find_the_best_person": "Encontre a pessoa mais indicada disponível e percorra sua equipe.",
"fixed_round_robin": "Round-robin fixo", "fixed_round_robin": "Round-robin fixo",
"add_one_fixed_attendee": "Adicione um participante fixo e utilize o round-robin em uma determinada quantidade de participantes.", "add_one_fixed_attendee": "Adicione um participante fixo e utilize o round-robin em uma determinada quantidade de participantes.",
"calcom_is_better_with_team": "{{appName}} é melhor com equipes",
"the_calcom_team": "A equipe de {{companyName}}",
"add_your_team_members": "Adicione membros da sua equipe aos seus tipos de evento. Use programação coletiva para incluir todos ou encontre a pessoa mais apropriada pela programação com round-robin.", "add_your_team_members": "Adicione membros da sua equipe aos seus tipos de evento. Use programação coletiva para incluir todos ou encontre a pessoa mais apropriada pela programação com round-robin.",
"booking_limit_reached": "O limite de reseva para este tipo de evento foi atingido", "booking_limit_reached": "O limite de reseva para este tipo de evento foi atingido",
"duration_limit_reached": "O limite de duração para este tipo de evento foi atingido", "duration_limit_reached": "O limite de duração para este tipo de evento foi atingido",
@@ -1525,6 +1538,7 @@
"navigate_installed_apps": "Ir para aplicativos instalados", "navigate_installed_apps": "Ir para aplicativos instalados",
"disabled_calendar": "Se você tiver outro calendário instalado, novas reservas serão adicionadas a ele. Caso contrário, conecte um novo calendário para não perder novas reservas.", "disabled_calendar": "Se você tiver outro calendário instalado, novas reservas serão adicionadas a ele. Caso contrário, conecte um novo calendário para não perder novas reservas.",
"enable_apps": "Ativar aplicativos", "enable_apps": "Ativar aplicativos",
"enable_apps_description": "Ative aplicativos que os usuários podem integrar com o {{appName}}",
"purchase_license": "Comprar uma licença", "purchase_license": "Comprar uma licença",
"already_have_key": "Já tenho uma chave:", "already_have_key": "Já tenho uma chave:",
"already_have_key_suggestion": "Copie a variável de ambiente CALCOM_LICENSE_KEY existente aqui.", "already_have_key_suggestion": "Copie a variável de ambiente CALCOM_LICENSE_KEY existente aqui.",
@@ -1538,6 +1552,9 @@
"no_available_apps": "Não há aplicativos disponíveis", "no_available_apps": "Não há aplicativos disponíveis",
"no_available_apps_description": "Verifique se há aplicativos na sua implantação, em \"packages/app-store\"", "no_available_apps_description": "Verifique se há aplicativos na sua implantação, em \"packages/app-store\"",
"no_apps": "Não há aplicativos ativados nesta instância do Cal", "no_apps": "Não há aplicativos ativados nesta instância do Cal",
"no_apps_configured": "Nenhum aplicativo foi configurado ainda",
"enable_in_settings": "Você pode habilitar aplicativos nas configurações",
"please_contact_admin": "Entre em contato com o administrador",
"apps_settings": "Configurações do app", "apps_settings": "Configurações do app",
"fill_this_field": "Preencha este campo", "fill_this_field": "Preencha este campo",
"options": "Opções", "options": "Opções",
@@ -1641,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "Você tem certeza que deseja remover a configuração de {{connectionType}}? Os membros do seu time que utilizam {{connectionType}} para fazer login não conseguirão acessar o Cal.com.", "delete_sso_configuration_confirmation_description": "Você tem certeza que deseja remover a configuração de {{connectionType}}? Os membros do seu time que utilizam {{connectionType}} para fazer login não conseguirão acessar o Cal.com.",
"organizer_timezone": "Fuso horário do organizador", "organizer_timezone": "Fuso horário do organizador",
"email_user_cta": "Ver convite", "email_user_cta": "Ver convite",
"email_no_user_invite_heading": "Você recebeu um convite para ingressar em {{entity}} de {{appName}}",
"email_no_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar em sua equipe em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que sua equipe agende reuniões sem precisar trocar e-mails.", "email_no_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar em sua equipe em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que sua equipe agende reuniões sem precisar trocar e-mails.",
"email_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar na equipe \"{{teamName}}\" de {{entity}} em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que {{entity}} agende reuniões sem precisar trocar e-mails.",
"email_no_user_invite_steps_intro": "Orientaremos ao longo de alguns passos rápidos para que você comece logo a agendar eventos com {{entity}} sem preocupação.",
"email_no_user_step_one": "Escolha seu nome de usuário", "email_no_user_step_one": "Escolha seu nome de usuário",
"email_no_user_step_two": "Conecte com sua conta de calendário", "email_no_user_step_two": "Conecte com sua conta de calendário",
"email_no_user_step_three": "Defina sua disponibilidade", "email_no_user_step_three": "Defina sua disponibilidade",
@@ -1652,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "Sem fluxos de trabalho", "no_workflows": "Sem fluxos de trabalho",
"change_filter": "Mude o filtro para ver seus fluxos de trabalho pessoais e da equipe.", "change_filter": "Mude o filtro para ver seus fluxos de trabalho pessoais e da equipe.",
"change_filter_common": "Altere o filtro para ver os resultados.",
"no_results_for_filter": "Nenhum resultado para filtrar",
"recommended_next_steps": "Próximos passos recomendados", "recommended_next_steps": "Próximos passos recomendados",
"create_a_managed_event": "Crie um tipo de evento gerenciado", "create_a_managed_event": "Crie um tipo de evento gerenciado",
"meetings_are_better_with_the_right": "Reuniões são melhores com a presença dos membros certos da equipe. Convide-os agora.", "meetings_are_better_with_the_right": "Reuniões são melhores com a presença dos membros certos da equipe. Convide-os agora.",
@@ -1662,7 +1684,9 @@
"no_longer_attending": "Você não está mais participando deste evento", "no_longer_attending": "Você não está mais participando deste evento",
"attendee_no_longer_attending_subject": "Um participante não está mais participando de {{title}} às {{date}}", "attendee_no_longer_attending_subject": "Um participante não está mais participando de {{title}} às {{date}}",
"attendee_no_longer_attending": "Um participante não está mais participando do seu evento", "attendee_no_longer_attending": "Um participante não está mais participando do seu evento",
"attendee_no_longer_attending_subtitle": "{{name}} cancelou. Quer dizer que um assento foi liberado para este período de tempo",
"create_event_on": "Criar evento em", "create_event_on": "Criar evento em",
"create_routing_form_on": "Criar formulário de roteamento em",
"default_app_link_title": "Defina um link padrão para o app", "default_app_link_title": "Defina um link padrão para o app",
"default_app_link_description": "Definir um link padrão para o app permite que todos os tipos de evento recém-criados usem o link definido para o app.", "default_app_link_description": "Definir um link padrão para o app permite que todos os tipos de evento recém-criados usem o link definido para o app.",
"organizer_default_conferencing_app": "Aplicativo padrão do organizador", "organizer_default_conferencing_app": "Aplicativo padrão do organizador",
@@ -1672,6 +1696,7 @@
"booking_questions_title": "Perguntas sobre reserva", "booking_questions_title": "Perguntas sobre reserva",
"booking_questions_description": "Personalize as perguntas feitas na página de reservas", "booking_questions_description": "Personalize as perguntas feitas na página de reservas",
"add_a_booking_question": "Adicione uma pergunta", "add_a_booking_question": "Adicione uma pergunta",
"identifier": "Identificador",
"duplicate_email": "Este e-mail já existe", "duplicate_email": "Este e-mail já existe",
"booking_with_payment_cancelled": "Não é mais possível pagar por este evento", "booking_with_payment_cancelled": "Não é mais possível pagar por este evento",
"booking_with_payment_cancelled_already_paid": "Um reembolso pelo pagamento desta reserva está a caminho.", "booking_with_payment_cancelled_already_paid": "Um reembolso pelo pagamento desta reserva está a caminho.",
@@ -1682,6 +1707,7 @@
"show_on_booking_page": "Mostrar na página de reservas", "show_on_booking_page": "Mostrar na página de reservas",
"get_started_zapier_templates": "Comece agora com modelos do Zapier", "get_started_zapier_templates": "Comece agora com modelos do Zapier",
"team_is_unpublished": "Publicação de {{team}} cancelada", "team_is_unpublished": "Publicação de {{team}} cancelada",
"team_is_unpublished_description": "O link de {{entity}} não está disponível por enquanto. Fale com o proprietário de {{entity}} ou peça que seja publicado.",
"team_member": "Membro da equipe", "team_member": "Membro da equipe",
"a_routing_form": "Formulário de roteamento", "a_routing_form": "Formulário de roteamento",
"form_description_placeholder": "Descrição do formulário", "form_description_placeholder": "Descrição do formulário",
@@ -1711,13 +1737,16 @@
"spot_popular_event_types": "Localizar tipos de evento populares", "spot_popular_event_types": "Localizar tipos de evento populares",
"spot_popular_event_types_description": "Veja quais tipos de eventos estão recebendo a maioria dos cliques e reservas", "spot_popular_event_types_description": "Veja quais tipos de eventos estão recebendo a maioria dos cliques e reservas",
"no_responses_yet": "Sem respostas por enquanto", "no_responses_yet": "Sem respostas por enquanto",
"no_routes_defined": "Nenhuma rota definida",
"this_will_be_the_placeholder": "Este será o espaço reservado", "this_will_be_the_placeholder": "Este será o espaço reservado",
"error_booking_event": "Ocorreu um erro ao reservar o evento, atualize a página e tente novamente",
"timeslot_missing_title": "Nenhuma alocação de tempo selecionada", "timeslot_missing_title": "Nenhuma alocação de tempo selecionada",
"timeslot_missing_description": "Selecione uma alocação de tempo para reservar o evento.", "timeslot_missing_description": "Selecione uma alocação de tempo para reservar o evento.",
"timeslot_missing_cta": "Selecione a alocação de tempo", "timeslot_missing_cta": "Selecione a alocação de tempo",
"switch_monthly": "Trocar para visualização mensal", "switch_monthly": "Trocar para visualização mensal",
"switch_weekly": "Trocar para visualização semanal", "switch_weekly": "Trocar para visualização semanal",
"switch_multiday": "Trocar para visualização diária", "switch_multiday": "Trocar para visualização diária",
"switch_columnview": "Trocar para visualização de coluna",
"num_locations": "{{num}} opções de local", "num_locations": "{{num}} opções de local",
"select_on_next_step": "Selecione na próxima etapa", "select_on_next_step": "Selecione na próxima etapa",
"this_meeting_has_not_started_yet": "Esta reunião ainda não começou", "this_meeting_has_not_started_yet": "Esta reunião ainda não começou",
@@ -1756,6 +1785,7 @@
"managed_event_dialog_title_one": "O url/{{slug}} já existe para {{count}} membro. Deseja substituir?", "managed_event_dialog_title_one": "O url/{{slug}} já existe para {{count}} membro. Deseja substituir?",
"managed_event_dialog_title_other": "O url/{{slug}} já existe para {{count}} membros. Deseja substituir?", "managed_event_dialog_title_other": "O url/{{slug}} já existe para {{count}} membros. Deseja substituir?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> já está usando o url <strong>/{{slug}}</strong>.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> já está usando o url <strong>/{{slug}}</strong>.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> já estão usando o url <strong>/{{slug}}</strong>.",
"managed_event_dialog_clarification": "Se você escolher substituir, serão enviadas notificações. Volte e remova caso não queira sobrescrever.", "managed_event_dialog_clarification": "Se você escolher substituir, serão enviadas notificações. Volte e remova caso não queira sobrescrever.",
"review_event_type": "Revisar tipo de evento", "review_event_type": "Revisar tipo de evento",
"looking_for_more_analytics": "Procurando mais análises?", "looking_for_more_analytics": "Procurando mais análises?",
@@ -1771,12 +1801,14 @@
"least_booked_members": "Membros com menos reservas", "least_booked_members": "Membros com menos reservas",
"events_created": "Eventos criados", "events_created": "Eventos criados",
"events_completed": "Eventos concluídos", "events_completed": "Eventos concluídos",
"events_cancelled": "Eventos cancelados",
"events_rescheduled": "Eventos reagendados", "events_rescheduled": "Eventos reagendados",
"from_last_period": "do último período", "from_last_period": "do último período",
"from_to_date_period": "De: {{startDate}} Para: {{endDate}}", "from_to_date_period": "De: {{startDate}} Para: {{endDate}}",
"redirect_url_warning": "A página de sucesso será desabilitada ao adicionar um redirecionamento. Não se esqueça de mencionar \"Reserva confirmada\" na sua página de sucesso personalizada.", "redirect_url_warning": "A página de sucesso será desabilitada ao adicionar um redirecionamento. Não se esqueça de mencionar \"Reserva confirmada\" na sua página de sucesso personalizada.",
"event_trends": "Tendências de evento", "event_trends": "Tendências de evento",
"clear_filters": "Limpar filtros", "clear_filters": "Limpar filtros",
"clear": "Limpar",
"hold": "Segurar", "hold": "Segurar",
"on_booking_option": "Coletar pagamento na reserva", "on_booking_option": "Coletar pagamento na reserva",
"hold_option": "Carregar taxa de não comparecimento", "hold_option": "Carregar taxa de não comparecimento",
@@ -1803,6 +1835,18 @@
"complete_your_booking": "Conclua sua reserva", "complete_your_booking": "Conclua sua reserva",
"complete_your_booking_subject": "Conclua sua reserva: {{title}} à(s) {{date}}", "complete_your_booking_subject": "Conclua sua reserva: {{title}} à(s) {{date}}",
"confirm_your_details": "Confirme suas informações", "confirm_your_details": "Confirme suas informações",
"copy_invite_link": "Copiar link de convite",
"edit_invite_link": "Editar configurações do link",
"invite_link_copied": "Link de convite copiado",
"invite_link_deleted": "Link de convite excluído",
"invite_link_updated": "Configurações do link de convite salvas",
"link_expires_after": "Link configurado para expirar após...",
"one_day": "1 dia",
"seven_days": "7 dias",
"thirty_days": "30 dias",
"three_months": "3 meses",
"one_year": "1 ano",
"team_invite_received": "Você recebeu um convite para ingressar em {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Você está prestes a cobrar {{amount, currency}} do participante. Tem certeza de que deseja continuar?", "charge_card_dialog_body": "Você está prestes a cobrar {{amount, currency}} do participante. Tem certeza de que deseja continuar?",
"charge_attendee": "Cobrar {{amount, currency}} do participante", "charge_attendee": "Cobrar {{amount, currency}} do participante",
@@ -1811,6 +1855,7 @@
"email_invite_team_bulk": "{{userCount}} usuários foram convidados", "email_invite_team_bulk": "{{userCount}} usuários foram convidados",
"error_collecting_card": "Erro ao coletar cartão", "error_collecting_card": "Erro ao coletar cartão",
"image_size_limit_exceed": "A imagem carregada não deve ultrapassar o limite de 5 MB", "image_size_limit_exceed": "A imagem carregada não deve ultrapassar o limite de 5 MB",
"unauthorized_workflow_error_message": "{{errorCode}}: você não tem autorização para habilidar ou desabilitar este fluxo de trabalho",
"inline_embed": "Inserção embutida", "inline_embed": "Inserção embutida",
"load_inline_content": "Carrega seu tipo de evento embutido diretamente no conteúdo restante do site.", "load_inline_content": "Carrega seu tipo de evento embutido diretamente no conteúdo restante do site.",
"floating_pop_up_button": "Botão pop-up flutuante", "floating_pop_up_button": "Botão pop-up flutuante",
@@ -1830,6 +1875,69 @@
"connect_google_workspace": "Conectar com o Google Workspace", "connect_google_workspace": "Conectar com o Google Workspace",
"google_workspace_admin_tooltip": "Você deve ser administrador do Google Workspace para usar este recurso", "google_workspace_admin_tooltip": "Você deve ser administrador do Google Workspace para usar este recurso",
"first_event_type_webhook_description": "Crie seu primeiro webhook para este tipo de evento", "first_event_type_webhook_description": "Crie seu primeiro webhook para este tipo de evento",
"install_app_on": "Instalar aplicativo em",
"create_for": "Criar para", "create_for": "Criar para",
"insights_all_org_filter": "Todos os apps" "setup_organization": "Definir uma Organização",
"organization_banner_description": "Crie um ambiente onde suas equipes podem criar tipos de evento, fluxos de trabalho e aplicativos compartilhados com agendamento coletivo e round robin.",
"organization_banner_title": "Gerenciar organizações com múltiplas equipes",
"set_up_your_organization": "Configurar sua organização",
"organizations_description": "Organizações são ambientes compartilhados em que as equipes podem criar fluxos de trabalho, aplicativos, tipos de evento compartilhados e muito mais.",
"must_enter_organization_name": "Requer um nome de organização",
"must_enter_organization_admin_email": "Requer o endereço de e-mail da sua organização",
"admin_email": "Endereço de e-mail da sua organização",
"admin_username": "Nome do usuário do administrador",
"organization_name": "Nome da organização",
"organization_url": "URL da organização",
"organization_verify_header": "Verifique o e-mail da sua organização",
"organization_verify_email_body": "Use o código abaixo para verificar seu endereço de e-mail e continuar a configuração da sua organização.",
"additional_url_parameters": "Parâmetros adicionais de URL",
"about_your_organization": "Sobre a sua organização",
"about_your_organization_description": "Organizações são ambientes compartilhados em que você pode criar múltiplas equipes com membros, fluxos de trabalho, aplicativos, tipos de evento compartilhados e muito mais.",
"create_your_teams": "Criar suas equipes",
"create_your_teams_description": "Comece a agendar juntos ao adicionar os membros das suas equipes à sua organização",
"invite_organization_admins": "Convidar administradores da sua organização",
"invite_organization_admins_description": "Estes administradores terão acesso a todas as equipes na sua organização. Você pode adicionar administradores e membros da equipe mais tarde.",
"set_a_password": "Definir senha",
"set_a_password_description": "Será criada uma nova conta de usuário com o e-mail da sua organização e esta senha.",
"organization_logo": "Logotipo da organização",
"organization_about_description": "Uma breve descrição sobre sua organização. Isso aparecerá na página do perfli público da sua organização.",
"ill_do_this_later": "Farei isso mais tarde",
"verify_your_email": "Verifique seu e-mail",
"enter_digit_code": "Insira o código de seis dígitos enviado para {{email}}",
"verify_email_organization": "Verifique seu e-mail para criar uma organização",
"code_provided_invalid": "O código inserido não é válido, tente novamente",
"email_already_used": "Este e-mail já está sendo usado",
"organization_admin_invited_heading": "Você recebeu um convite para ingressar em {{orgName}}",
"organization_admin_invited_body": "Ingresse na sua equipe em {{orgName}} e comece a focar na reunião, não em fazer reuniões!",
"duplicated_slugs_warning": "Não foi possível criar as equipes a seguir devido a campos de dados dinâmicos: {{slugs}}",
"team_names_empty": "Nomes de equipe não podem ser vazios",
"team_names_repeated": "Nomes de equipe não podem ser repetidos",
"user_belongs_organization": "O usuário pertence a uma organização",
"org_no_teams_yet": "Esta organização ainda não tem nenhuma equipe",
"org_no_teams_yet_description": "Se você for administrador, não se esqueça de criar equipes para mostrar aqui.",
"set_up": "Configurar",
"set_up_your_profile": "Configurar seu perfil",
"set_up_your_profile_description": "Deixe que as pessoas saibam quem você é em {{orgName}} e quando interagirem com seu link público.",
"my_profile": "Meu perfil",
"my_settings": "Minhas configurações",
"crm": "CRM",
"messaging": "Mensagens",
"sender_id_info": "Nome ou número mostrado como remetente do SMS (alguns países não permitem IDs de remetentes com caracteres alfanuméricos)",
"org_admins_can_create_new_teams": "Apenas o administrador da sua organização pode criar equipes novas",
"google_new_spam_policy": "A nova política de spams do Google pode impedir o recebimento de notificações do calendário e e-mail sobre esta reserva.",
"resolve": "Resolver",
"no_organization_slug": "Houve um erro ao criar equipes para esta organizazção. Falta o campo de dados dinâmico da URL.",
"org_name": "Nome da organização",
"org_url": "URL da organização",
"copy_link_org": "Copiar link para a organização",
"404_the_org": "A organização",
"404_the_team": "A equipe",
"404_claim_entity_org": "Solicite o subdomínio para a sua organização",
"404_claim_entity_team": "Solicite esta equipe e comece a gerenciar agendamentos coletivamente",
"insights_all_org_filter": "Todos os apps",
"insights_team_filter": "Equipe: {{teamName}}",
"insights_user_filter": "Usuário: {{userName}}",
"insights_subtitle": "Veja insights de reserva em seus eventos",
"custom_plan": "Plano personalizado",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Adicione suas novas strings aqui em cima ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+171 -1
View File
@@ -14,12 +14,20 @@
"verify_email_subject": "{{appName}}: Подтвердите учетную запись", "verify_email_subject": "{{appName}}: Подтвердите учетную запись",
"check_your_email": "Проверьте почту", "check_your_email": "Проверьте почту",
"verify_email_page_body": "Мы отправили письмо на адрес {{email}}. Обязательно подтвердите адрес электронной почты, чтобы электронная почта и календарь {{appName}} работали с максимальной эффективностью.", "verify_email_page_body": "Мы отправили письмо на адрес {{email}}. Обязательно подтвердите адрес электронной почты, чтобы электронная почта и календарь {{appName}} работали с максимальной эффективностью.",
"verify_email_banner_body": "Подтвердите адрес электронной почты, чтобы электронная почта и календарь работали с максимальной эффективностью",
"verify_email_email_header": "Подтвердите ваш адрес электронной почты",
"verify_email_email_button": "Подтвердите адрес электронной почты",
"verify_email_email_body": "Подтвердите адрес электронной почты, нажав кнопку ниже.",
"verify_email_email_link_text": "Вот ссылка на случай, если вы не любите нажимать на кнопки:",
"email_sent": "Письмо успешно отправлено",
"event_declined_subject": "Отклонено: {{title}} {{date}}", "event_declined_subject": "Отклонено: {{title}} {{date}}",
"event_cancelled_subject": "Отмена: {{title}} {{date}}", "event_cancelled_subject": "Отмена: {{title}} {{date}}",
"event_request_declined": "Ваш запрос на встречу отклонен", "event_request_declined": "Ваш запрос на встречу отклонен",
"event_request_declined_recurring": "Ваш запрос на повторяющееся событие отклонен", "event_request_declined_recurring": "Ваш запрос на повторяющееся событие отклонен",
"event_request_cancelled": "Ваша запланированная встреча была отменена",
"organizer": "Организатор", "organizer": "Организатор",
"need_to_reschedule_or_cancel": "Хотите перенести или отменить?", "need_to_reschedule_or_cancel": "Хотите перенести или отменить?",
"no_options_available": "Нет доступных вариантов",
"cancellation_reason": "Причина отмены (необязательно)", "cancellation_reason": "Причина отмены (необязательно)",
"cancellation_reason_placeholder": "Укажите причину отмены подписки", "cancellation_reason_placeholder": "Укажите причину отмены подписки",
"rejection_reason": "Причина отказа", "rejection_reason": "Причина отказа",
@@ -79,7 +87,9 @@
"your_meeting_has_been_booked": "Ваша встреча была забронирована", "your_meeting_has_been_booked": "Ваша встреча была забронирована",
"event_type_has_been_rescheduled_on_time_date": "Ваше {{title}} было перенесено на {{date}}.", "event_type_has_been_rescheduled_on_time_date": "Ваше {{title}} было перенесено на {{date}}.",
"event_has_been_rescheduled": "Ваше событие было перенесено.", "event_has_been_rescheduled": "Ваше событие было перенесено.",
"request_reschedule_subtitle": "{{organizer}} отменил(-а) бронирование и попросил(-а) вас выбрать другое время.",
"request_reschedule_title_organizer": "Вы запросили у {{attendee}} изменение расписания", "request_reschedule_title_organizer": "Вы запросили у {{attendee}} изменение расписания",
"request_reschedule_subtitle_organizer": "Вы отменили бронирование; теперь {{attendee}} и вам нужно выбрать новое время.",
"rescheduled_event_type_subject": "Запрос на перенос отправлен: {{eventType}} с {{name}}, {{date}}", "rescheduled_event_type_subject": "Запрос на перенос отправлен: {{eventType}} с {{name}}, {{date}}",
"requested_to_reschedule_subject_attendee": "Требуется перенести бронирование: забронируйте новое время для {{eventType}} с {{name}}", "requested_to_reschedule_subject_attendee": "Требуется перенести бронирование: забронируйте новое время для {{eventType}} с {{name}}",
"hi_user_name": "Привет {{name}}", "hi_user_name": "Привет {{name}}",
@@ -120,6 +130,7 @@
"upgrade_banner_action": "Изменить", "upgrade_banner_action": "Изменить",
"team_upgraded_successfully": "Вы успешно перешли на новый тариф для своей команды!", "team_upgraded_successfully": "Вы успешно перешли на новый тариф для своей команды!",
"org_upgrade_banner_description": "Спасибо, что попробовали наш новый тариф Organization. Для работы с «{{teamName}}» нужно перейти на тариф Organization.", "org_upgrade_banner_description": "Спасибо, что попробовали наш новый тариф Organization. Для работы с «{{teamName}}» нужно перейти на тариф Organization.",
"org_upgraded_successfully": "Вы успешно перешли на тариф Organization!",
"use_link_to_reset_password": "Используйте ссылку ниже, чтобы сбросить пароль", "use_link_to_reset_password": "Используйте ссылку ниже, чтобы сбросить пароль",
"hey_there": "Привет,", "hey_there": "Привет,",
"forgot_your_password_calcom": "Забыли пароль? - {{appName}}", "forgot_your_password_calcom": "Забыли пароль? - {{appName}}",
@@ -186,6 +197,7 @@
"blog": "Блог", "blog": "Блог",
"blog_description": "Прочитайте наши последние новости и статьи", "blog_description": "Прочитайте наши последние новости и статьи",
"join_our_community": "Присоединяйтесь к нашему сообществу", "join_our_community": "Присоединяйтесь к нашему сообществу",
"join_our_discord": "Присоединяйтесь к нам в Discord",
"404_claim_entity_user": "Забронируйте своё имя пользователя и начните планировать встречи", "404_claim_entity_user": "Забронируйте своё имя пользователя и начните планировать встречи",
"popular_pages": "Популярные страницы", "popular_pages": "Популярные страницы",
"register_now": "Зарегистрироваться", "register_now": "Зарегистрироваться",
@@ -193,6 +205,7 @@
"page_doesnt_exist": "Эта страница не существует.", "page_doesnt_exist": "Эта страница не существует.",
"check_spelling_mistakes_or_go_back": "Проверьте наличие ошибок, или вернитесь на предыдущую страницу.", "check_spelling_mistakes_or_go_back": "Проверьте наличие ошибок, или вернитесь на предыдущую страницу.",
"404_page_not_found": "404: Страница не найдена.", "404_page_not_found": "404: Страница не найдена.",
"booker_event_not_found": "Нам не удалось найти событие, которое вы пытаетесь забронировать.",
"getting_started": "Начало работы", "getting_started": "Начало работы",
"15min_meeting": "Встреча на 15 минут", "15min_meeting": "Встреча на 15 минут",
"30min_meeting": "Встреча на 30 минут", "30min_meeting": "Встреча на 30 минут",
@@ -228,11 +241,14 @@
"done": "Готово", "done": "Готово",
"all_done": "Готово!", "all_done": "Готово!",
"all": "Все приложения", "all": "Все приложения",
"yours": "Ваш аккаунт",
"available_apps": "Доступные приложения", "available_apps": "Доступные приложения",
"check_email_reset_password": "Проверьте вашу электронную почту, мы отправили вам ссылку для сброса пароля.", "check_email_reset_password": "Проверьте вашу электронную почту, мы отправили вам ссылку для сброса пароля.",
"finish": "Завершить", "finish": "Завершить",
"organization_general_description": "Настройте язык и часовой пояс для своей команды",
"few_sentences_about_yourself": "Напишите несколько предложений о себе. Они будут отображаться на вашей публичной странице.", "few_sentences_about_yourself": "Напишите несколько предложений о себе. Они будут отображаться на вашей публичной странице.",
"nearly_there": "Почти готово!", "nearly_there": "Почти готово!",
"nearly_there_instructions": "И последнее: добавьте краткую информацию о себе и свою фотографию; так людям будет проще понять, с кем они бронируют встречу.",
"set_availability_instructions": "Определите диапазон времени, в который вы обычно доступны. В дальнейшем можно будет добавить ещё диапазоны и назначить их разным календарям.", "set_availability_instructions": "Определите диапазон времени, в который вы обычно доступны. В дальнейшем можно будет добавить ещё диапазоны и назначить их разным календарям.",
"set_availability": "Задайте время в которое вы доступны", "set_availability": "Задайте время в которое вы доступны",
"continue_without_calendar": "Продолжить без подключения календаря", "continue_without_calendar": "Продолжить без подключения календаря",
@@ -288,7 +304,18 @@
"success": "Успешно", "success": "Успешно",
"failed": "Ошибка", "failed": "Ошибка",
"password_has_been_reset_login": "Ваш пароль был сброшен. Теперь вы можете войти с новым паролем.", "password_has_been_reset_login": "Ваш пароль был сброшен. Теперь вы можете войти с новым паролем.",
"layout": "Макет",
"bookerlayout_default_title": "Представление по умолчанию",
"bookerlayout_description": "Вы можете выбрать несколько представлений; пользователи, оформляющие бронирование, могут переключать представления.",
"bookerlayout_user_settings_title": "Макет забронированного события",
"bookerlayout_user_settings_description": "Вы можете выбрать несколько представлений; пользователи, оформляющие бронирование, могут переключать представления. Эту настройку можно переопределять для каждого события.",
"bookerlayout_month_view": "Месяц",
"bookerlayout_week_view": "Еженедельно", "bookerlayout_week_view": "Еженедельно",
"bookerlayout_column_view": "Столбец",
"bookerlayout_error_min_one_enabled": "Нужно выбрать по крайней мере один макет.",
"bookerlayout_error_default_not_enabled": "Макет, который вы выбрали как представление по умолчанию, не входит в число доступных макетов.",
"bookerlayout_error_unknown_layout": "Вы выбрали недопустимый макет.",
"bookerlayout_override_global_settings": "Эту настройку можно указать для всех типов событий в <2>настройках / оформление</2> или <6>переопределить только для этого события</6>.",
"unexpected_error_try_again": "Произошла непредвиденная ошибка. Попробуйте еще раз.", "unexpected_error_try_again": "Произошла непредвиденная ошибка. Попробуйте еще раз.",
"sunday_time_error": "Недопустимое время в воскресенье", "sunday_time_error": "Недопустимое время в воскресенье",
"monday_time_error": "Недопустимое время в понедельник", "monday_time_error": "Недопустимое время в понедельник",
@@ -301,6 +328,7 @@
"error_end_time_next_day": "Время окончания не может позже 24 часов", "error_end_time_next_day": "Время окончания не может позже 24 часов",
"back_to_bookings": "Вернуться к списку бронирований", "back_to_bookings": "Вернуться к списку бронирований",
"free_to_pick_another_event_type": "Вы можете выбрать любое другое событие.", "free_to_pick_another_event_type": "Вы можете выбрать любое другое событие.",
"cancelled": "Отменено",
"cancellation_successful": "Отмена прошла успешно", "cancellation_successful": "Отмена прошла успешно",
"really_cancel_booking": "Вы действительно хотите отменить бронирование?", "really_cancel_booking": "Вы действительно хотите отменить бронирование?",
"cannot_cancel_booking": "Вы не можете отменить это бронирование", "cannot_cancel_booking": "Вы не можете отменить это бронирование",
@@ -309,6 +337,12 @@
"cancelling_event_recurring": "Данное событие — один из экземпляров повторяющегося события.", "cancelling_event_recurring": "Данное событие — один из экземпляров повторяющегося события.",
"cancelling_all_recurring": "Это все оставшиеся экземпляры повторяющегося события.", "cancelling_all_recurring": "Это все оставшиеся экземпляры повторяющегося события.",
"error_with_status_code_occured": "Произошла ошибка с кодом состояния {{status}}.", "error_with_status_code_occured": "Произошла ошибка с кодом состояния {{status}}.",
"error_event_type_url_duplicate": "Тип события с этим URL-адресом уже существует.",
"error_event_type_unauthorized_create": "Вы не можете создать это событие",
"error_event_type_unauthorized_update": "Вы не можете редактировать это событие",
"error_workflow_unauthorized_create": "Вы не можете создать этот рабочий процесс",
"error_schedule_unauthorized_create": "Вы не можете создать это расписание",
"booking_already_cancelled": "Это бронирование уже отменено",
"booking_already_accepted_rejected": "Это бронирование уже принято или отклонено", "booking_already_accepted_rejected": "Это бронирование уже принято или отклонено",
"go_back_home": "Вернуться домой", "go_back_home": "Вернуться домой",
"or_go_back_home": "Или вернитесь домой", "or_go_back_home": "Или вернитесь домой",
@@ -318,10 +352,12 @@
"no_status_bookings_yet_description": "У вас нет {{status}} бронирований. {{description}}", "no_status_bookings_yet_description": "У вас нет {{status}} бронирований. {{description}}",
"event_between_users": "{{eventName}} между {{host}} и {{attendeeName}}", "event_between_users": "{{eventName}} между {{host}} и {{attendeeName}}",
"bookings": "Бронирования", "bookings": "Бронирования",
"booking_not_found": "Бронирование не найдено",
"bookings_description": "Просматривайте предстоящие и прошедшие события, забронированные по ссылкам событий.", "bookings_description": "Просматривайте предстоящие и прошедшие события, забронированные по ссылкам событий.",
"upcoming_bookings": "Как только кто-то забронирует встречу с вами она будет отображена здесь.", "upcoming_bookings": "Как только кто-то забронирует встречу с вами она будет отображена здесь.",
"recurring_bookings": "Как только кто-то забронирует повторяющуюся встречу с вами, она будет отображена здесь.", "recurring_bookings": "Как только кто-то забронирует повторяющуюся встречу с вами, она будет отображена здесь.",
"past_bookings": "Здесь появятся ваши прошлые бронирования.", "past_bookings": "Здесь появятся ваши прошлые бронирования.",
"cancelled_bookings": "Здесь появятся ваши отменённые бронирования.",
"unconfirmed_bookings": "Здесь можно увидеть бронирования, которые вы еще не подтвердили.", "unconfirmed_bookings": "Здесь можно увидеть бронирования, которые вы еще не подтвердили.",
"unconfirmed_bookings_tooltip": "Неподтвержденные бронирования", "unconfirmed_bookings_tooltip": "Неподтвержденные бронирования",
"on": "на", "on": "на",
@@ -355,15 +391,19 @@
"user_dynamic_booking_disabled": "Некоторые участники группы отключили функцию динамического группового бронирования", "user_dynamic_booking_disabled": "Некоторые участники группы отключили функцию динамического группового бронирования",
"allow_dynamic_booking_tooltip": "Ссылки для группового бронирования, которые можно создавать динамически, указывая несколько имен пользователей при помощи знака «+». Пример: «{{appName}}/bailey+peer»", "allow_dynamic_booking_tooltip": "Ссылки для группового бронирования, которые можно создавать динамически, указывая несколько имен пользователей при помощи знака «+». Пример: «{{appName}}/bailey+peer»",
"allow_dynamic_booking": "Разрешить участникам бронировать встречи с вами при помощи динамического группового бронирования", "allow_dynamic_booking": "Разрешить участникам бронировать встречи с вами при помощи динамического группового бронирования",
"dynamic_booking": "Динамические ссылки группы",
"email": "Адрес электронной почты", "email": "Адрес электронной почты",
"email_placeholder": "jdoe@example.com", "email_placeholder": "jdoe@example.com",
"full_name": "Имя", "full_name": "Имя",
"browse_api_documentation": "Посмотрите нашу документацию API", "browse_api_documentation": "Посмотрите нашу документацию API",
"leverage_our_api": "Используйте наш API для возможности полного управления и настройки.", "leverage_our_api": "Используйте наш API для возможности полного управления и настройки.",
"create_webhook": "Создать веб-хук", "create_webhook": "Создать веб-хук",
"booking_cancelled": "Бронирование отменено",
"booking_rescheduled": "Бронирование изменено", "booking_rescheduled": "Бронирование изменено",
"recording_ready": "Ссылка для скачивания записи готова", "recording_ready": "Ссылка для скачивания записи готова",
"booking_created": "Бронирование создано", "booking_created": "Бронирование создано",
"booking_rejected": "Бронирование отклонено",
"booking_requested": "Поступил запрос на бронирование",
"meeting_ended": "Встреча завершилась", "meeting_ended": "Встреча завершилась",
"form_submitted": "Форма отправлена", "form_submitted": "Форма отправлена",
"event_triggers": "Триггеры событий", "event_triggers": "Триггеры событий",
@@ -373,6 +413,8 @@
"team_webhooks": "Командные вебхуки", "team_webhooks": "Командные вебхуки",
"create_new_webhook_to_account": "Создайте новый вебхук для вашей учетной записи", "create_new_webhook_to_account": "Создайте новый вебхук для вашей учетной записи",
"new_webhook": "Новый веб-хук", "new_webhook": "Новый веб-хук",
"receive_cal_meeting_data": "Получайте данные о создании или отмене встреч в {{appName}} по указанному URL-адресу в реальном времени.",
"receive_cal_event_meeting_data": "Получайте данные о планировании или отмене этого события в {{appName}} по указанному URL-адресу в реальном времени.",
"responsive_fullscreen_iframe": "Адаптивный полноэкранный iframe", "responsive_fullscreen_iframe": "Адаптивный полноэкранный iframe",
"loading": "Загрузка...", "loading": "Загрузка...",
"deleting": "Выполняется удаление...", "deleting": "Выполняется удаление...",
@@ -435,6 +477,7 @@
"max_limit_allowed_hint": "Не более {{limit}} символов", "max_limit_allowed_hint": "Не более {{limit}} символов",
"invalid_password_hint": "Пароль должен быть не короче {{passwordLength}} символов и содержать заглавные и строчные буквы, а также не менее одной цифры", "invalid_password_hint": "Пароль должен быть не короче {{passwordLength}} символов и содержать заглавные и строчные буквы, а также не менее одной цифры",
"incorrect_password": "Неверный пароль", "incorrect_password": "Неверный пароль",
"incorrect_email_password": "Неверный адрес электронной почты или пароль.",
"use_setting": "Использовать настройки", "use_setting": "Использовать настройки",
"am_pm": "am/pm", "am_pm": "am/pm",
"time_options": "Настройки времени", "time_options": "Настройки времени",
@@ -462,6 +505,7 @@
"additional_guests": "Добавить гостей", "additional_guests": "Добавить гостей",
"your_name": "Ваше имя", "your_name": "Ваше имя",
"your_full_name": "ФИО", "your_full_name": "ФИО",
"no_name": "Нет имени",
"email_address": "Адрес электронной почты", "email_address": "Адрес электронной почты",
"enter_valid_email": "Укажите допустимый адрес электронной почты", "enter_valid_email": "Укажите допустимый адрес электронной почты",
"location": "Местоположение", "location": "Местоположение",
@@ -505,7 +549,9 @@
"your_team_updated_successfully": "Ваша команда успешно обновлена.", "your_team_updated_successfully": "Ваша команда успешно обновлена.",
"about": "О нас", "about": "О нас",
"team_description": "Краткое описание вашей команды. Этот текст будет показываться на странице вашей команды.", "team_description": "Краткое описание вашей команды. Этот текст будет показываться на странице вашей команды.",
"org_description": "Краткое описание вашей организации. Этот текст будет виден на странице вашей организации.",
"members": "Участники", "members": "Участники",
"organization_members": "Сотрудники организации",
"member": "Участник", "member": "Участник",
"number_member_one": "Участники: {{count}}", "number_member_one": "Участники: {{count}}",
"number_member_other": "Участники: {{count}}", "number_member_other": "Участники: {{count}}",
@@ -540,6 +586,8 @@
"confirm_all": "Подтвердить все", "confirm_all": "Подтвердить все",
"disband_team": "Распустить команду", "disband_team": "Распустить команду",
"disband_team_confirmation_message": "Вы уверены, что хотите распустить эту команду? Любой, с кем вы поделились ссылкой на эту команду, больше не сможет забронировать её.", "disband_team_confirmation_message": "Вы уверены, что хотите распустить эту команду? Любой, с кем вы поделились ссылкой на эту команду, больше не сможет забронировать её.",
"disband_org": "Распустить организацию",
"disband_org_confirmation_message": "Распустить эту организацию? Все команды и сотрудники будут удалены.",
"remove_member_confirmation_message": "Вы уверены, что хотите удалить этого участника из команды?", "remove_member_confirmation_message": "Вы уверены, что хотите удалить этого участника из команды?",
"confirm_disband_team": "Да, распустить команду", "confirm_disband_team": "Да, распустить команду",
"confirm_remove_member": "Да, удалить участника", "confirm_remove_member": "Да, удалить участника",
@@ -614,6 +662,7 @@
"event_type_updated_successfully": "Тип события {{eventTypeTitle}} успешно обновлен", "event_type_updated_successfully": "Тип события {{eventTypeTitle}} успешно обновлен",
"event_type_deleted_successfully": "Тип события успешно удален", "event_type_deleted_successfully": "Тип события успешно удален",
"hours": "Часы", "hours": "Часы",
"people": "Люди",
"your_email": "Ваш адрес электронной почты", "your_email": "Ваш адрес электронной почты",
"change_avatar": "Изменить аватар", "change_avatar": "Изменить аватар",
"language": "Язык", "language": "Язык",
@@ -646,9 +695,11 @@
"create_new_team": "Создание новой команды", "create_new_team": "Создание новой команды",
"open_invitations": "Открыть список приглашений", "open_invitations": "Открыть список приглашений",
"new_team": "Новая команда", "new_team": "Новая команда",
"create_first_team_and_invite_others": "Создайте свою первую команду и пригласите других пользователей работать вместе с вами.",
"create_team_to_get_started": "Создайте команду, чтобы начать работу", "create_team_to_get_started": "Создайте команду, чтобы начать работу",
"teams": "Команды", "teams": "Команды",
"team": "Команда", "team": "Команда",
"organization": "Организация",
"team_billing": "Условия расчета для команд", "team_billing": "Условия расчета для команд",
"team_billing_description": "Управление биллингом вашей команды", "team_billing_description": "Управление биллингом вашей команды",
"upgrade_to_flexible_pro_title": "Мы изменили условия расчета для команд", "upgrade_to_flexible_pro_title": "Мы изменили условия расчета для команд",
@@ -723,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}} создаст ссылку на встречу в Huddle01 Web3.", "cal_provide_huddle01_meeting_url": "{{appName}} создаст ссылку на встречу в Huddle01 Web3.",
"cal_provide_teams_meeting_url": "{{appName}} предоставит URL-адрес встречи в MS Teams. ПРИМЕЧАНИЕ: У ВАС ДОЛЖЕН БЫТЬ КОРПОРАТИВНЫЙ ИЛИ СТУДЕНЧЕСКИЙ АККАУНТ", "cal_provide_teams_meeting_url": "{{appName}} предоставит URL-адрес встречи в MS Teams. ПРИМЕЧАНИЕ: У ВАС ДОЛЖЕН БЫТЬ КОРПОРАТИВНЫЙ ИЛИ СТУДЕНЧЕСКИЙ АККАУНТ",
"require_payment": "Требуется оплата", "require_payment": "Требуется оплата",
"you_need_to_add_a_name": "Нужно добавить имя",
"commission_per_transaction": "комиссия за сделку", "commission_per_transaction": "комиссия за сделку",
"event_type_updated_successfully_description": "Ваш шаблон события успешно обновлён.", "event_type_updated_successfully_description": "Ваш шаблон события успешно обновлён.",
"hide_event_type": "Скрыть шаблон события", "hide_event_type": "Скрыть шаблон события",
@@ -813,18 +865,25 @@
"installed_apps": "Установленные приложения", "installed_apps": "Установленные приложения",
"free_to_use_apps": "Бесплатные", "free_to_use_apps": "Бесплатные",
"no_category_apps": "Нет приложений в категории «{{category}}»", "no_category_apps": "Нет приложений в категории «{{category}}»",
"all_apps": "Все приложения",
"no_category_apps_description_calendar": "Добавьте приложение календаря, чтобы проверять наличие конфликтов для избежания двойного бронирования", "no_category_apps_description_calendar": "Добавьте приложение календаря, чтобы проверять наличие конфликтов для избежания двойного бронирования",
"no_category_apps_description_conferencing": "Попробуйте добавить приложение конференц-связи для интеграции видеозвонков с клиентами",
"no_category_apps_description_payment": "Добавьте платежное приложение, чтобы упростить транзакции с клиентами", "no_category_apps_description_payment": "Добавьте платежное приложение, чтобы упростить транзакции с клиентами",
"no_category_apps_description_analytics": "Добавьте приложение аналитики для использования на страницах бронирования", "no_category_apps_description_analytics": "Добавьте приложение аналитики для использования на страницах бронирования",
"no_category_apps_description_automation": "Добавьте приложение для автоматизации", "no_category_apps_description_automation": "Добавьте приложение для автоматизации",
"no_category_apps_description_other": "Добавляйте всевозможные приложения для решения своих задач", "no_category_apps_description_other": "Добавляйте всевозможные приложения для решения своих задач",
"no_category_apps_description_web3": "Добавьте приложение web3 для использования на страницах бронирования", "no_category_apps_description_web3": "Добавьте приложение web3 для использования на страницах бронирования",
"no_category_apps_description_messaging": "Добавьте мессенджер, чтобы настроить пользовательские уведомления и напоминания",
"no_category_apps_description_crm": "Добавьте CRM, чтобы отслеживать, с кем у вас были встречи",
"installed_app_calendar_description": "Настройте проверку календарей на предмет конфликтов для избежания двойного бронирования.", "installed_app_calendar_description": "Настройте проверку календарей на предмет конфликтов для избежания двойного бронирования.",
"installed_app_payment_description": "Выберите службы обработки платежей для получения оплаты от клиентов.", "installed_app_payment_description": "Выберите службы обработки платежей для получения оплаты от клиентов.",
"installed_app_analytics_description": "Выберите приложения аналитики для страниц бронирования", "installed_app_analytics_description": "Выберите приложения аналитики для страниц бронирования",
"installed_app_other_description": "Все установленные приложения из других категорий.", "installed_app_other_description": "Все установленные приложения из других категорий.",
"installed_app_conferencing_description": "Выберите приложения для видеоконференций",
"installed_app_automation_description": "Выберите приложения для автоматизации", "installed_app_automation_description": "Выберите приложения для автоматизации",
"installed_app_web3_description": "Выберите приложения web3 для страниц бронирования", "installed_app_web3_description": "Выберите приложения web3 для страниц бронирования",
"installed_app_messaging_description": "Выберите мессенджеры, в которых вы хотите настроить пользовательские уведомления и напоминания",
"installed_app_crm_description": "Выберите CRM-приложения, в которых вы хотите отслеживать, с кем у вас были встречи",
"analytics": "Аналитика", "analytics": "Аналитика",
"empty_installed_apps_headline": "Нет установленных приложений", "empty_installed_apps_headline": "Нет установленных приложений",
"empty_installed_apps_description": "Приложения позволяют значительно улучшить рабочий процесс и жить по расписанию.", "empty_installed_apps_description": "Приложения позволяют значительно улучшить рабочий процесс и жить по расписанию.",
@@ -850,6 +909,7 @@
"create_events_on": "Создавать события в календаре:", "create_events_on": "Создавать события в календаре:",
"enterprise_license": "Это функция корпоративного тарифного плана", "enterprise_license": "Это функция корпоративного тарифного плана",
"enterprise_license_description": "Чтобы включить эту функцию, получите ключ развертывания на консоли {{consoleUrl}} и добавьте его в .env как CALCOM_LICENSE_KEY. Если у вашей команды уже есть лицензия, пожалуйста, обратитесь за помощью в {{supportMail}}.", "enterprise_license_description": "Чтобы включить эту функцию, получите ключ развертывания на консоли {{consoleUrl}} и добавьте его в .env как CALCOM_LICENSE_KEY. Если у вашей команды уже есть лицензия, пожалуйста, обратитесь за помощью в {{supportMail}}.",
"enterprise_license_development": "Протестируйте эту функцию в режиме разработки. Для использования в рабочем режиме администратор должен перейти по ссылке <2>/auth/setup</2> и ввести лицензионный ключ.",
"missing_license": "Отсутствует лицензия", "missing_license": "Отсутствует лицензия",
"signup_requires": "Требуется коммерческая лицензия", "signup_requires": "Требуется коммерческая лицензия",
"signup_requires_description": "В настоящее время компания {{companyName}} не предлагает бесплатную версию страницы регистрации с открытым исходным кодом. Чтобы получить полный доступ к компонентам входа в систему, необходимо приобрести коммерческую лицензию. Для личного пользования мы рекомендуем Prisma Data Platform или любой другой интерфейс Postgres для создания учетных записей.", "signup_requires_description": "В настоящее время компания {{companyName}} не предлагает бесплатную версию страницы регистрации с открытым исходным кодом. Чтобы получить полный доступ к компонентам входа в систему, необходимо приобрести коммерческую лицензию. Для личного пользования мы рекомендуем Prisma Data Platform или любой другой интерфейс Postgres для создания учетных записей.",
@@ -919,6 +979,7 @@
"confirm_delete_api_key": "Отозвать ключ API", "confirm_delete_api_key": "Отозвать ключ API",
"revoke_api_key": "Отозвать ключ API", "revoke_api_key": "Отозвать ключ API",
"api_key_copied": "Ключ API скопирован.", "api_key_copied": "Ключ API скопирован.",
"api_key_expires_on": "Срок действия ключа API истекает",
"delete_api_key_confirm_title": "Удалить этот ключ API из вашего аккаунта навсегда?", "delete_api_key_confirm_title": "Удалить этот ключ API из вашего аккаунта навсегда?",
"copy": "Копировать", "copy": "Копировать",
"expire_date": "Срок действия", "expire_date": "Срок действия",
@@ -941,6 +1002,9 @@
"user_impersonation_heading": "Вход от имени пользователя", "user_impersonation_heading": "Вход от имени пользователя",
"user_impersonation_description": "Позволяет нашей службе поддержки временно входить в систему от вашего имени, чтобы быстро решать любые проблемы, о которых вы нам сообщаете.", "user_impersonation_description": "Позволяет нашей службе поддержки временно входить в систему от вашего имени, чтобы быстро решать любые проблемы, о которых вы нам сообщаете.",
"team_impersonation_description": "Позволяет участникам и администраторам вашей команды временно входить в систему под вашим именем.", "team_impersonation_description": "Позволяет участникам и администраторам вашей команды временно входить в систему под вашим именем.",
"make_team_private": "Сделать команду защищенной",
"make_team_private_description": "Если эта опция включена, участники вашей команды не смогут видеть других участников команды.",
"you_cannot_see_team_members": "Вы не можете видеть всех участников защищенной команды.",
"allow_booker_to_select_duration": "Разрешить пользователю, оформляющему бронирование, выбирать длительность", "allow_booker_to_select_duration": "Разрешить пользователю, оформляющему бронирование, выбирать длительность",
"impersonate_user_tip": "Все варианты использования этой функции проверяются.", "impersonate_user_tip": "Все варианты использования этой функции проверяются.",
"impersonating_user_warning": "Олицетворение пользователя \"{{user}}\".", "impersonating_user_warning": "Олицетворение пользователя \"{{user}}\".",
@@ -1008,17 +1072,21 @@
"event_location": "Местоположение события", "event_location": "Местоположение события",
"reschedule_optional": "Причина переноса (дополнительно)", "reschedule_optional": "Причина переноса (дополнительно)",
"reschedule_placeholder": "Расскажите другим, почему вам нужно изменить расписание", "reschedule_placeholder": "Расскажите другим, почему вам нужно изменить расписание",
"event_cancelled": "Это событие отменено",
"emailed_information_about_cancelled_event": "Мы сообщили об этом вам и другим участникам по электронной почте.", "emailed_information_about_cancelled_event": "Мы сообщили об этом вам и другим участникам по электронной почте.",
"this_input_will_shown_booking_this_event": "Этот вопрос будет показан при бронировании события по этому шаблону", "this_input_will_shown_booking_this_event": "Этот вопрос будет показан при бронировании события по этому шаблону",
"meeting_url_in_conformation_email": "Ссылка на встречу находится в письме с подтверждением", "meeting_url_in_conformation_email": "Ссылка на встречу находится в письме с подтверждением",
"url_start_with_https": "URL-адрес должен начинаться с http:// или https://", "url_start_with_https": "URL-адрес должен начинаться с http:// или https://",
"number_provided": "Будет указан номер телефона", "number_provided": "Будет указан номер телефона",
"before_event_trigger": "до начала события", "before_event_trigger": "до начала события",
"event_cancelled_trigger": "когда событие отменено",
"new_event_trigger": "когда будет забронировано новое событие", "new_event_trigger": "когда будет забронировано новое событие",
"email_host_action": "отправить письмо организатору", "email_host_action": "отправить письмо организатору",
"email_attendee_action": "отправить письмо участникам", "email_attendee_action": "отправить письмо участникам",
"sms_attendee_action": "Отправить SMS-сообщение участнику",
"sms_number_action": "отправка SMS-сообщение на указанный номер", "sms_number_action": "отправка SMS-сообщение на указанный номер",
"whatsapp_number_action": "отправка сообщение в Whatsapp на указанный номер", "whatsapp_number_action": "отправка сообщение в Whatsapp на указанный номер",
"whatsapp_attendee_action": "отправить участнику сообщение в Whatsapp",
"workflows": "Рабочие процессы", "workflows": "Рабочие процессы",
"new_workflow_btn": "Новый рабочий процесс", "new_workflow_btn": "Новый рабочий процесс",
"add_new_workflow": "Добавить новый рабочий процесс", "add_new_workflow": "Добавить новый рабочий процесс",
@@ -1181,6 +1249,7 @@
"start_of_week": "Начало недели", "start_of_week": "Начало недели",
"recordings_title": "Записи", "recordings_title": "Записи",
"recording": "Запись", "recording": "Запись",
"happy_scheduling": "Счастливого планирования",
"select_calendars": "Выберите, в каких календарях нужно проверить наличие конфликтов и дублированного бронирования.", "select_calendars": "Выберите, в каких календарях нужно проверить наличие конфликтов и дублированного бронирования.",
"check_for_conflicts": "Проверить наличие конфликтов", "check_for_conflicts": "Проверить наличие конфликтов",
"view_recordings": "Просмотреть записи", "view_recordings": "Просмотреть записи",
@@ -1222,6 +1291,7 @@
"conferencing_description": "Настройка приложений для видеоконференций, используемых для проведения онлайн-встреч", "conferencing_description": "Настройка приложений для видеоконференций, используемых для проведения онлайн-встреч",
"add_conferencing_app": "Добавить приложение для видеоконференций", "add_conferencing_app": "Добавить приложение для видеоконференций",
"password_description": "Настройка паролей для аккаунта", "password_description": "Настройка паролей для аккаунта",
"set_up_two_factor_authentication": "Настроить двухфакторную аутентификацию",
"we_just_need_basic_info": "Для настройки вашего профиля необходимо указать основную информацию.", "we_just_need_basic_info": "Для настройки вашего профиля необходимо указать основную информацию.",
"skip": "Пропустить", "skip": "Пропустить",
"do_this_later": "Настроить позже", "do_this_later": "Настроить позже",
@@ -1235,6 +1305,8 @@
"connect_analytics_apps": "Подключить приложения аналитики", "connect_analytics_apps": "Подключить приложения аналитики",
"connect_other_apps": "Подключить другие приложения", "connect_other_apps": "Подключить другие приложения",
"connect_web3_apps": "Подключить приложения web3", "connect_web3_apps": "Подключить приложения web3",
"connect_messaging_apps": "Подключить мессенджеры",
"connect_crm_apps": "Подключить CRM-приложения",
"current_step_of_total": "Шаг {{currentStep}} из {{maxSteps}}", "current_step_of_total": "Шаг {{currentStep}} из {{maxSteps}}",
"add_variable": "Добавить переменную", "add_variable": "Добавить переменную",
"custom_phone_number": "Номер телефона для отправки уведомлений", "custom_phone_number": "Номер телефона для отправки уведомлений",
@@ -1247,12 +1319,14 @@
"location_info": "Место проведения события", "location_info": "Место проведения события",
"additional_notes_info": "Дополнительные заметки о бронировании", "additional_notes_info": "Дополнительные заметки о бронировании",
"attendee_name_info": "Участник, на которого оформляется бронирование", "attendee_name_info": "Участник, на которого оформляется бронирование",
"organizer_name_info": "Имя организатора",
"to": "Кому", "to": "Кому",
"workflow_turned_on_successfully": "Состояние рабочего процесса «{{workflowName}}» изменено на «{{offOn}}»", "workflow_turned_on_successfully": "Состояние рабочего процесса «{{workflowName}}» изменено на «{{offOn}}»",
"download_responses": "Скачать ответы", "download_responses": "Скачать ответы",
"download_responses_description": "Скачать все ответы пользователей, заполнивших форму, в формате CSV.", "download_responses_description": "Скачать все ответы пользователей, заполнивших форму, в формате CSV.",
"download": "Скачать", "download": "Скачать",
"download_recording": "Скачать запись", "download_recording": "Скачать запись",
"recording_from_your_recent_call": "Запись вашего недавнего созвана в {{appName}} готова для скачивания",
"create_your_first_form": "Создайте первую форму", "create_your_first_form": "Создайте первую форму",
"create_your_first_form_description": "Формы маршрутизации позволяют задавать пользователям уточняющие вопросы, чтобы перенаправлять их к соответствующему лицу или типу события.", "create_your_first_form_description": "Формы маршрутизации позволяют задавать пользователям уточняющие вопросы, чтобы перенаправлять их к соответствующему лицу или типу события.",
"create_your_first_webhook": "Создайте свой первый вебхук", "create_your_first_webhook": "Создайте свой первый вебхук",
@@ -1261,7 +1335,9 @@
"event_one": "событие", "event_one": "событие",
"event_other": "событий", "event_other": "событий",
"profile_team_description": "Настройка профиля вашей команды", "profile_team_description": "Настройка профиля вашей команды",
"profile_org_description": "Настроить профиль организации",
"members_team_description": "Пользователи, входящие в группу", "members_team_description": "Пользователи, входящие в группу",
"organization_description": "Управляйте администраторами и сотрудниками вашей организации",
"team_url": "URL-адрес команды", "team_url": "URL-адрес команды",
"team_members": "Участники команды", "team_members": "Участники команды",
"more": "Еще", "more": "Еще",
@@ -1302,6 +1378,7 @@
"routing_forms_send_email_owner": "Отправляйте письма владельцу", "routing_forms_send_email_owner": "Отправляйте письма владельцу",
"routing_forms_send_email_owner_description": "Отправляйте владельцу формы электронное письмо, когда пользователь ее заполняет", "routing_forms_send_email_owner_description": "Отправляйте владельцу формы электронное письмо, когда пользователь ее заполняет",
"add_new_form": "Добавить новую форму", "add_new_form": "Добавить новую форму",
"add_new_team_form": "Добавить новую форму в команду",
"create_your_first_route": "Создайте первый маршрут", "create_your_first_route": "Создайте первый маршрут",
"route_to_the_right_person": "Перенаправляйте клиентов к нужному участнику команды исходя из ответов при заполнении формы", "route_to_the_right_person": "Перенаправляйте клиентов к нужному участнику команды исходя из ответов при заполнении формы",
"form_description": "Создайте форму для перенаправления пользователей при бронировании", "form_description": "Создайте форму для перенаправления пользователей при бронировании",
@@ -1387,6 +1464,7 @@
"new_event_type_availability": "{{eventTypeTitle}} | Доступность", "new_event_type_availability": "{{eventTypeTitle}} | Доступность",
"error_editing_availability": "Ошибка при редактировании доступности", "error_editing_availability": "Ошибка при редактировании доступности",
"dont_have_permission": "У вас нет разрешения на доступ к этому ресурсу.", "dont_have_permission": "У вас нет разрешения на доступ к этому ресурсу.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Пожалуйста, вставьте здесь метаданные SAML от вашего провайдера", "saml_configuration_placeholder": "Пожалуйста, вставьте здесь метаданные SAML от вашего провайдера",
"saml_email_required": "Пожалуйста, введите адрес электронной почты, чтобы мы могли найти ваш SAML идентификатор провайдера", "saml_email_required": "Пожалуйста, введите адрес электронной почты, чтобы мы могли найти ваш SAML идентификатор провайдера",
"saml_sp_title": "Детали поставщика услуг", "saml_sp_title": "Детали поставщика услуг",
@@ -1405,15 +1483,19 @@
"yearly": "Ежегодная", "yearly": "Ежегодная",
"checkout": "Оплатить заказ", "checkout": "Оплатить заказ",
"your_team_disbanded_successfully": "Ваша команда расформирована", "your_team_disbanded_successfully": "Ваша команда расформирована",
"your_org_disbanded_successfully": "Ваша организация расформирована",
"error_creating_team": "Ошибка при создании команды", "error_creating_team": "Ошибка при создании команды",
"you": "Вы", "you": "Вы",
"resend_email": "Отправить письмо еще раз",
"member_already_invited": "Участник уже приглашен", "member_already_invited": "Участник уже приглашен",
"enter_email_or_username": "Введите адрес электронной почты или имя пользователя", "enter_email_or_username": "Введите адрес электронной почты или имя пользователя",
"team_name_taken": "Это название уже занято", "team_name_taken": "Это название уже занято",
"must_enter_team_name": "Необходимо ввести название команды", "must_enter_team_name": "Необходимо ввести название команды",
"team_url_required": "Необходимо ввести URL-адрес команды", "team_url_required": "Необходимо ввести URL-адрес команды",
"url_taken": "Этот URL-адрес уже занят", "url_taken": "Этот URL-адрес уже занят",
"problem_registering_domain": "Возникла проблема с регистрацией поддомена. Попробуйте еще раз или свяжитесь с администратором",
"team_publish": "Опубликовать команду", "team_publish": "Опубликовать команду",
"number_text_notifications": "Номер телефона (SMS-уведомления)",
"attendee_email_variable": "Электронная почта участника", "attendee_email_variable": "Электронная почта участника",
"attendee_email_info": "Электронная почта участника, на которого оформляется бронирование", "attendee_email_info": "Электронная почта участника, на которого оформляется бронирование",
"kbar_search_placeholder": "Введите команду или начните поиск...", "kbar_search_placeholder": "Введите команду или начните поиск...",
@@ -1436,6 +1518,8 @@
"find_the_best_person": "Выбирайте наиболее подходящего сотрудника из команды в порядке очередности.", "find_the_best_person": "Выбирайте наиболее подходящего сотрудника из команды в порядке очередности.",
"fixed_round_robin": "Фиксированная очередность", "fixed_round_robin": "Фиксированная очередность",
"add_one_fixed_attendee": "Добавьте одного фиксированного участника и назначайте участников по очереди.", "add_one_fixed_attendee": "Добавьте одного фиксированного участника и назначайте участников по очереди.",
"calcom_is_better_with_team": "{{appName}} отлично подходит для командной работы",
"the_calcom_team": "Команда {{companyName}}",
"add_your_team_members": "Добавьте участников команды к типам мероприятий. Благодаря совместному планированию можно включить в мероприятие всех пользователей или найти наиболее подходящего пользователя с циклическим планированием.", "add_your_team_members": "Добавьте участников команды к типам мероприятий. Благодаря совместному планированию можно включить в мероприятие всех пользователей или найти наиболее подходящего пользователя с циклическим планированием.",
"booking_limit_reached": "Достигнут лимит бронирования для этого типа события", "booking_limit_reached": "Достигнут лимит бронирования для этого типа события",
"duration_limit_reached": "Достигнут лимит продолжительности бронирования для этого типа события", "duration_limit_reached": "Достигнут лимит продолжительности бронирования для этого типа события",
@@ -1454,6 +1538,7 @@
"navigate_installed_apps": "Перейти к установленным приложениям", "navigate_installed_apps": "Перейти к установленным приложениям",
"disabled_calendar": "Если у вас установлен другой календарь, в него будут добавляться новые бронирования. Если у вас нет установленного календаря, подключите новый календарь, чтобы не пропускать новые бронирования.", "disabled_calendar": "Если у вас установлен другой календарь, в него будут добавляться новые бронирования. Если у вас нет установленного календаря, подключите новый календарь, чтобы не пропускать новые бронирования.",
"enable_apps": "Включить приложения", "enable_apps": "Включить приложения",
"enable_apps_description": "Выберите приложения, которые пользователи могут интегрировать с {{appName}}",
"purchase_license": "Купить лицензию", "purchase_license": "Купить лицензию",
"already_have_key": "У меня уже есть ключ:", "already_have_key": "У меня уже есть ключ:",
"already_have_key_suggestion": "Скопируйте сюда переменную окружения CALCOM_LICENSE_KEY.", "already_have_key_suggestion": "Скопируйте сюда переменную окружения CALCOM_LICENSE_KEY.",
@@ -1467,6 +1552,9 @@
"no_available_apps": "Нет доступных приложений", "no_available_apps": "Нет доступных приложений",
"no_available_apps_description": "Убедитесь, что в вашей установке в 'packages/app-store' есть приложения", "no_available_apps_description": "Убедитесь, что в вашей установке в 'packages/app-store' есть приложения",
"no_apps": "В этом экземпляре Cal нет включенных приложений", "no_apps": "В этом экземпляре Cal нет включенных приложений",
"no_apps_configured": "Нет настроенных приложений",
"enable_in_settings": "Выберите приложения в настройках",
"please_contact_admin": "Свяжитесь с вашим администратором",
"apps_settings": "Настройки приложений", "apps_settings": "Настройки приложений",
"fill_this_field": "Заполните это поле", "fill_this_field": "Заполните это поле",
"options": "Настройки", "options": "Настройки",
@@ -1573,6 +1661,7 @@
"email_no_user_invite_heading": "Вас пригласили в {{appName}} {{entity}}", "email_no_user_invite_heading": "Вас пригласили в {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в команду в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.", "email_no_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в команду в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.",
"email_user_invite_subheading": "{{invitedBy}} пригласил(а) вас в команду {{entity}} `{{teamName}}` в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого вы и ваша компания {{entity}} можете планировать встречи без утомительной переписки по электронной почте.", "email_user_invite_subheading": "{{invitedBy}} пригласил(а) вас в команду {{entity}} `{{teamName}}` в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого вы и ваша компания {{entity}} можете планировать встречи без утомительной переписки по электронной почте.",
"email_no_user_invite_steps_intro": "Всего несколько шагов — и вы сможете оперативно и без стресса планировать встречи с {{entity}}.",
"email_no_user_step_one": "Выберите имя пользователя", "email_no_user_step_one": "Выберите имя пользователя",
"email_no_user_step_two": "Подключите аккаунт календаря", "email_no_user_step_two": "Подключите аккаунт календаря",
"email_no_user_step_three": "Задайте время, в которое вы доступны", "email_no_user_step_three": "Задайте время, в которое вы доступны",
@@ -1584,6 +1673,7 @@
"no_workflows": "Нет рабочих процессов", "no_workflows": "Нет рабочих процессов",
"change_filter": "Измените фильтр, чтобы видеть свои рабочие процессы и рабочие процессы своей команды.", "change_filter": "Измените фильтр, чтобы видеть свои рабочие процессы и рабочие процессы своей команды.",
"change_filter_common": "Измените фильтр, чтобы увидеть результаты.", "change_filter_common": "Измените фильтр, чтобы увидеть результаты.",
"no_results_for_filter": "Поиск с заданным фильтром не дал результатов",
"recommended_next_steps": "Рекомендуемые следующие шаги", "recommended_next_steps": "Рекомендуемые следующие шаги",
"create_a_managed_event": "Создайте тип событий, которыми вы будете управлять", "create_a_managed_event": "Создайте тип событий, которыми вы будете управлять",
"meetings_are_better_with_the_right": "Встречи проходят эффективнее, когда на них присутствуют подходящие участники команды. Пригласите их сейчас.", "meetings_are_better_with_the_right": "Встречи проходят эффективнее, когда на них присутствуют подходящие участники команды. Пригласите их сейчас.",
@@ -1594,6 +1684,7 @@
"no_longer_attending": "Вы отказались от посещения этого мероприятия", "no_longer_attending": "Вы отказались от посещения этого мероприятия",
"attendee_no_longer_attending_subject": "Участник отказался от посещения мероприятия {{title}} в {{date}}", "attendee_no_longer_attending_subject": "Участник отказался от посещения мероприятия {{title}} в {{date}}",
"attendee_no_longer_attending": "Участник отказался от посещения вашего мероприятия", "attendee_no_longer_attending": "Участник отказался от посещения вашего мероприятия",
"attendee_no_longer_attending_subtitle": "{{name}} отказался(-ась) от посещения мероприятия. Этот промежуток времени снова свободен",
"create_event_on": "Создать событие в календаре", "create_event_on": "Создать событие в календаре",
"create_routing_form_on": "Создать форму маршрутизации", "create_routing_form_on": "Создать форму маршрутизации",
"default_app_link_title": "Установить ссылку на приложение по умолчанию", "default_app_link_title": "Установить ссылку на приложение по умолчанию",
@@ -1605,6 +1696,7 @@
"booking_questions_title": "Вопросы при бронировании", "booking_questions_title": "Вопросы при бронировании",
"booking_questions_description": "Настройка вопросов, задаваемых пользователю на странице бронирования", "booking_questions_description": "Настройка вопросов, задаваемых пользователю на странице бронирования",
"add_a_booking_question": "Добавить вопрос", "add_a_booking_question": "Добавить вопрос",
"identifier": "Идентификатор",
"duplicate_email": "Адрес электронной почты уже существует", "duplicate_email": "Адрес электронной почты уже существует",
"booking_with_payment_cancelled": "Оплата этого события больше невозможна", "booking_with_payment_cancelled": "Оплата этого события больше невозможна",
"booking_with_payment_cancelled_already_paid": "Выполняется возврат оплаты за бронирование.", "booking_with_payment_cancelled_already_paid": "Выполняется возврат оплаты за бронирование.",
@@ -1645,13 +1737,16 @@
"spot_popular_event_types": "Определяйте наиболее популярные типы событий", "spot_popular_event_types": "Определяйте наиболее популярные типы событий",
"spot_popular_event_types_description": "Узнайте, какие типы событий собирают больше всего кликов и бронирований", "spot_popular_event_types_description": "Узнайте, какие типы событий собирают больше всего кликов и бронирований",
"no_responses_yet": "Ответов пока нет", "no_responses_yet": "Ответов пока нет",
"no_routes_defined": "Маршруты не определены",
"this_will_be_the_placeholder": "Это текст-заполнитель", "this_will_be_the_placeholder": "Это текст-заполнитель",
"error_booking_event": "При бронировании события произошла ошибка. Обновите страницу и повторите попытку",
"timeslot_missing_title": "Не выбран интервал времени", "timeslot_missing_title": "Не выбран интервал времени",
"timeslot_missing_description": "Чтобы забронировать событие, выберите интервал времени.", "timeslot_missing_description": "Чтобы забронировать событие, выберите интервал времени.",
"timeslot_missing_cta": "Выбрать интервал времени", "timeslot_missing_cta": "Выбрать интервал времени",
"switch_monthly": "Перейти в режим «месяц»", "switch_monthly": "Перейти в режим «месяц»",
"switch_weekly": "Перейти в режим «неделя»", "switch_weekly": "Перейти в режим «неделя»",
"switch_multiday": "Перейти в режим «день»", "switch_multiday": "Перейти в режим «день»",
"switch_columnview": "Перейти в режим «столбцы»",
"num_locations": "Варианты местоположений: {{num}}", "num_locations": "Варианты местоположений: {{num}}",
"select_on_next_step": "Выбрать на следующем этапе", "select_on_next_step": "Выбрать на следующем этапе",
"this_meeting_has_not_started_yet": "Эта встреча еще не началась", "this_meeting_has_not_started_yet": "Эта встреча еще не началась",
@@ -1706,12 +1801,14 @@
"least_booked_members": "Участники с наименьшим числом бронирований", "least_booked_members": "Участники с наименьшим числом бронирований",
"events_created": "Созданные события", "events_created": "Созданные события",
"events_completed": "Завершенные события", "events_completed": "Завершенные события",
"events_cancelled": "Отмененные события",
"events_rescheduled": "Перенесенные события", "events_rescheduled": "Перенесенные события",
"from_last_period": "с последнего периода", "from_last_period": "с последнего периода",
"from_to_date_period": "С: {{startDate}} По: {{endDate}}", "from_to_date_period": "С: {{startDate}} По: {{endDate}}",
"redirect_url_warning": "При использовании перенаправления страница успешного бронирования будет отключена. Не забудьте упомянуть «Бронирование подтверждено» на собственной странице оповещения об успешном бронировании.", "redirect_url_warning": "При использовании перенаправления страница успешного бронирования будет отключена. Не забудьте упомянуть «Бронирование подтверждено» на собственной странице оповещения об успешном бронировании.",
"event_trends": "Тренды событий", "event_trends": "Тренды событий",
"clear_filters": "Сбросить фильтры", "clear_filters": "Сбросить фильтры",
"clear": "Очистить",
"hold": "Заморозить", "hold": "Заморозить",
"on_booking_option": "Списывать оплату при бронировании", "on_booking_option": "Списывать оплату при бронировании",
"hold_option": "Взимать комиссию за неявку", "hold_option": "Взимать комиссию за неявку",
@@ -1738,7 +1835,18 @@
"complete_your_booking": "Завершить бронирование", "complete_your_booking": "Завершить бронирование",
"complete_your_booking_subject": "Завершите бронирование: {{title}}, {{date}}", "complete_your_booking_subject": "Завершите бронирование: {{title}}, {{date}}",
"confirm_your_details": "Подтвердите свои данные", "confirm_your_details": "Подтвердите свои данные",
"copy_invite_link": "Скопировать ссылку приглашения",
"edit_invite_link": "Изменить настройки ссылки",
"invite_link_copied": "Ссылка с приглашением скопирована",
"invite_link_deleted": "Ссылка на приглашение удалена",
"invite_link_updated": "Настройки ссылки с приглашением сохранены",
"link_expires_after": "Ссылки истекают через...", "link_expires_after": "Ссылки истекают через...",
"one_day": "1 день",
"seven_days": "7 дней",
"thirty_days": "30 дней",
"three_months": "3 месяца",
"one_year": "1 год",
"team_invite_received": "Вас пригласили в {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Вы собираетесь списать с участника {{amount, currency}}. Продолжить?", "charge_card_dialog_body": "Вы собираетесь списать с участника {{amount, currency}}. Продолжить?",
"charge_attendee": "Списать с участника {{amount, currency}}", "charge_attendee": "Списать с участника {{amount, currency}}",
@@ -1747,6 +1855,7 @@
"email_invite_team_bulk": "Приглашено пользователей: {{userCount}}", "email_invite_team_bulk": "Приглашено пользователей: {{userCount}}",
"error_collecting_card": "Ошибка при обработке карты", "error_collecting_card": "Ошибка при обработке карты",
"image_size_limit_exceed": "Размер загружаемого изображения не должен превышать 5 МБ", "image_size_limit_exceed": "Размер загружаемого изображения не должен превышать 5 МБ",
"unauthorized_workflow_error_message": "{{errorCode}}: У вас нет права включать или отключать этот рабочий процесс",
"inline_embed": "Встраивание в содержимое сайта", "inline_embed": "Встраивание в содержимое сайта",
"load_inline_content": "Отображение события вместе с другим содержимым сайта.", "load_inline_content": "Отображение события вместе с другим содержимым сайта.",
"floating_pop_up_button": "Плавающая кнопка", "floating_pop_up_button": "Плавающая кнопка",
@@ -1768,6 +1877,67 @@
"first_event_type_webhook_description": "Создайте первый вебхук для этого типа событий", "first_event_type_webhook_description": "Создайте первый вебхук для этого типа событий",
"install_app_on": "Установить приложение на", "install_app_on": "Установить приложение на",
"create_for": "Создать для", "create_for": "Создать для",
"setup_organization": "Настроить организацию",
"organization_banner_description": "Создайте среду, в которой ваши команды смогут открывать совместный доступ к приложениям, рабочим процессам и типам событий, составляя расписание совместно или по очереди.",
"organization_banner_title": "Управляйте организациями с несколькими командами",
"set_up_your_organization": "Настройте организацию",
"organizations_description": "Организация – это общая рабочая среда, в которой команды могут создавать общие типы событий, приложения, рабочие процессы и многое другое.",
"must_enter_organization_name": "Необходимо ввести название организации",
"must_enter_organization_admin_email": "Необходимо ввести адрес электронной почты вашей организации",
"admin_email": "Адрес электронной почты вашей организации",
"admin_username": "Имя пользователя администратора",
"organization_name": "Название организации",
"organization_url": "URL-адрес организации",
"organization_verify_header": "Подтвердите адрес электронной почты вашей организации",
"organization_verify_email_body": "С помощью кода ниже подтвердите свой адрес электронной почты, чтобы продолжить настройку организации.",
"additional_url_parameters": "Дополнительные параметры URL-адреса",
"about_your_organization": "Об организации",
"about_your_organization_description": "Организация – это общая рабочая среда, в которой можно создавать несколько команд с общими сотрудниками, типами событий, приложениями, рабочими процессами и т. п.",
"create_your_teams": "Создать команды",
"create_your_teams_description": "Добавьте участников команды в организацию и начните планировать дела вместе",
"invite_organization_admins": "Пригласите администраторов вашей организации",
"invite_organization_admins_description": "Эти администраторы будут иметь доступ ко всем командам вашей организации. Администраторов и участников команд можно добавить позже.",
"set_a_password": "Установить пароль",
"set_a_password_description": "Будет создан новый пользовательский аккаунт с адресом электронной почты вашей организации и этим паролем.",
"organization_logo": "Логотип организации",
"organization_about_description": "Краткое описание вашей организации. Этот текст будет виден в публичном профиле вашей организации.",
"ill_do_this_later": "Позже",
"verify_your_email": "Подтвердите адрес электронной почты",
"enter_digit_code": "Введите 6-значный код, который мы отправили на {{email}}",
"verify_email_organization": "Подтвердите свой адрес электронной почты для создания организации",
"code_provided_invalid": "Указанный код недействителен, попробуйте еще раз",
"email_already_used": "Адрес электронной почты уже используется",
"organization_admin_invited_heading": "Вас пригласили в {{orgName}}",
"organization_admin_invited_body": "Станьте частью команды {{orgName}} – и вы сможете уделять внимание встречам, а не их планированию!",
"duplicated_slugs_warning": "Не удалось создать следующие команды из-за дублирующихся слагов: {{slugs}}",
"team_names_empty": "Имена команд не могут быть пустыми",
"team_names_repeated": "Имена команд не могут быть повторяться",
"user_belongs_organization": "Пользователь относится к организации",
"org_no_teams_yet": "У этой организации еще нет команд",
"org_no_teams_yet_description": "Если вы администратор, не забудьте создать команды, которые будут отображаться здесь.",
"set_up": "Настроить",
"set_up_your_profile": "Настроить профиль",
"set_up_your_profile_description": "Расскажите, чем вы занимаетесь в {{orgName}}. Эта информация будет отобраться в ваших публичных ссылках.",
"my_profile": "Мой профиль",
"my_settings": "Мои настройки",
"crm": "CRM",
"messaging": "Сообщения",
"sender_id_info": "Имя или номер, отображаемые как отправитель SMS-сообщения (в некоторых странах не допускаются буквенно-цифровые идентификаторы)",
"org_admins_can_create_new_teams": "Только администратор вашей организации может создавать новые команды",
"google_new_spam_policy": "Из-за новой политики Google по выявлению спама вы можете не получить письма и уведомления календаря об этом забронированном событии.",
"resolve": "Разрешить",
"no_organization_slug": "При создании команд для этой организации произошла ошибка. Отсутствует слаг URL-адреса.",
"org_name": "Название организации",
"org_url": "URL-адрес организации",
"copy_link_org": "Скопировать ссылку на организацию",
"404_the_org": "Организация",
"404_the_team": "Команда",
"404_claim_entity_org": "Получите поддомен для вашей организации",
"404_claim_entity_team": "Направьте запрос в команду и начните составлять расписания вместе", "404_claim_entity_team": "Направьте запрос в команду и начните составлять расписания вместе",
"insights_all_org_filter": "Все приложения" "insights_all_org_filter": "Все приложения",
"insights_team_filter": "Команда: {{teamName}}",
"insights_user_filter": "Пользователь: {{userName}}",
"insights_subtitle": "Insights: просматривайте информацию о бронировании по всем вашим событиям",
"custom_plan": "Пользовательский тариф",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавьте строки выше ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+93 -1
View File
@@ -118,6 +118,7 @@
"team_info": "Ekip Bilgileri", "team_info": "Ekip Bilgileri",
"request_another_invitation_email": "{{appName}} e-posta adresiniz olarak {{toEmail}} adresini kullanmak istemiyorsanız veya zaten bir {{appName}} hesabınız varsa lütfen bu e-posta için başka bir davet talebinde bulunun.", "request_another_invitation_email": "{{appName}} e-posta adresiniz olarak {{toEmail}} adresini kullanmak istemiyorsanız veya zaten bir {{appName}} hesabınız varsa lütfen bu e-posta için başka bir davet talebinde bulunun.",
"you_have_been_invited": "{{teamName}} ekibine katılmaya davet edildiniz", "you_have_been_invited": "{{teamName}} ekibine katılmaya davet edildiniz",
"user_invited_you": "{{user}}, sizi {{appName}} uygulamasındaki {{entity}} {{team}} ekibine katılmaya davet etti",
"hidden_team_member_title": "Bu ekipte gizlisiniz", "hidden_team_member_title": "Bu ekipte gizlisiniz",
"hidden_team_member_message": "Yeriniz ücretli değil. Hesabınızı Pro'ya yükseltin veya ekip yöneticisinden yeriniz için ödeme yapmasını isteyin.", "hidden_team_member_message": "Yeriniz ücretli değil. Hesabınızı Pro'ya yükseltin veya ekip yöneticisinden yeriniz için ödeme yapmasını isteyin.",
"hidden_team_owner_message": "Ekipler özelliğini kullanmak için bir Pro hesabına ihtiyacınız var. Hesabınızı yükseltene kadar gizli olarak kalacaksınız.", "hidden_team_owner_message": "Ekipler özelliğini kullanmak için bir Pro hesabına ihtiyacınız var. Hesabınızı yükseltene kadar gizli olarak kalacaksınız.",
@@ -129,6 +130,7 @@
"upgrade_banner_action": "Buradan yükseltin", "upgrade_banner_action": "Buradan yükseltin",
"team_upgraded_successfully": "Ekibiniz başarıyla yükseltildi!", "team_upgraded_successfully": "Ekibiniz başarıyla yükseltildi!",
"org_upgrade_banner_description": "Yeni Kurumsal planımızı denediğiniz için teşekkür ederiz. \"{{teamName}}\" adlı kuruluşunuzun planının yükseltilmesi gerektiğini fark ettik.", "org_upgrade_banner_description": "Yeni Kurumsal planımızı denediğiniz için teşekkür ederiz. \"{{teamName}}\" adlı kuruluşunuzun planının yükseltilmesi gerektiğini fark ettik.",
"org_upgraded_successfully": "Kuruluşunuz başarıyla yükseltildi!",
"use_link_to_reset_password": "Şifrenizi sıfırlamak için aşağıdaki bağlantıyı kullanın", "use_link_to_reset_password": "Şifrenizi sıfırlamak için aşağıdaki bağlantıyı kullanın",
"hey_there": "Selam,", "hey_there": "Selam,",
"forgot_your_password_calcom": "Şifrenizi mi unuttunuz? - {{appName}}", "forgot_your_password_calcom": "Şifrenizi mi unuttunuz? - {{appName}}",
@@ -503,6 +505,7 @@
"additional_guests": "Misafir ekle", "additional_guests": "Misafir ekle",
"your_name": "Adınız", "your_name": "Adınız",
"your_full_name": "Tam adınız", "your_full_name": "Tam adınız",
"no_name": "Ad yok",
"email_address": "E-posta adresi", "email_address": "E-posta adresi",
"enter_valid_email": "Lütfen geçerli bir e-posta adresi girin", "enter_valid_email": "Lütfen geçerli bir e-posta adresi girin",
"location": "Konum", "location": "Konum",
@@ -546,6 +549,7 @@
"your_team_updated_successfully": "Ekibiniz başarıyla güncellendi.", "your_team_updated_successfully": "Ekibiniz başarıyla güncellendi.",
"about": "Hakkında", "about": "Hakkında",
"team_description": "Birkaç cümleyle ekibinizden bahsedin. Bu, ekibinizin URL sayfasında görünecektir.", "team_description": "Birkaç cümleyle ekibinizden bahsedin. Bu, ekibinizin URL sayfasında görünecektir.",
"org_description": "Birkaç cümleyle kuruluşunuzdan bahsedin. Bu, kuruluşunuzun URL sayfasında görünecektir.",
"members": "Üyeler", "members": "Üyeler",
"organization_members": "Kuruluş üyeleri", "organization_members": "Kuruluş üyeleri",
"member": "Üye", "member": "Üye",
@@ -582,6 +586,7 @@
"confirm_all": "Tümünü onayla", "confirm_all": "Tümünü onayla",
"disband_team": "Ekibi Dağıt", "disband_team": "Ekibi Dağıt",
"disband_team_confirmation_message": "Bu ekibi dağıtmak istediğinizden emin misiniz? Bu ekip bağlantısını paylaştığınız herkes artık bu bağlantıyı kullanarak rezervasyon yapamayacaktır.", "disband_team_confirmation_message": "Bu ekibi dağıtmak istediğinizden emin misiniz? Bu ekip bağlantısını paylaştığınız herkes artık bu bağlantıyı kullanarak rezervasyon yapamayacaktır.",
"disband_org": "Kuruluşu Dağıt",
"disband_org_confirmation_message": "Bu kuruluşu dağıtmak istediğinizden emin misiniz? Tüm ekipler ve üyeler silinecek.", "disband_org_confirmation_message": "Bu kuruluşu dağıtmak istediğinizden emin misiniz? Tüm ekipler ve üyeler silinecek.",
"remove_member_confirmation_message": "Bu üyeyi ekipten çıkarmak istediğinizden emin misiniz?", "remove_member_confirmation_message": "Bu üyeyi ekipten çıkarmak istediğinizden emin misiniz?",
"confirm_disband_team": "Evet, ekibi dağıt", "confirm_disband_team": "Evet, ekibi dağıt",
@@ -657,6 +662,7 @@
"event_type_updated_successfully": "{{eventTypeTitle}} etkinlik türü başarıyla güncellendi", "event_type_updated_successfully": "{{eventTypeTitle}} etkinlik türü başarıyla güncellendi",
"event_type_deleted_successfully": "Etkinlik türü başarıyla silindi", "event_type_deleted_successfully": "Etkinlik türü başarıyla silindi",
"hours": "Saat", "hours": "Saat",
"people": "İnsan",
"your_email": "E-postanız", "your_email": "E-postanız",
"change_avatar": "Avatarı değiştir", "change_avatar": "Avatarı değiştir",
"language": "Dil", "language": "Dil",
@@ -689,9 +695,11 @@
"create_new_team": "Yeni ekip oluştur", "create_new_team": "Yeni ekip oluştur",
"open_invitations": "Açık Davetler", "open_invitations": "Açık Davetler",
"new_team": "Yeni Ekip", "new_team": "Yeni Ekip",
"create_first_team_and_invite_others": "İlk ekibinizi oluşturun ve diğer kullanıcıları birlikte çalışmaya davet edin.",
"create_team_to_get_started": "Başlamak için bir ekip oluşturun", "create_team_to_get_started": "Başlamak için bir ekip oluşturun",
"teams": "Ekipler", "teams": "Ekipler",
"team": "Ekip", "team": "Ekip",
"organization": "Kuruluş",
"team_billing": "Ekip Faturası", "team_billing": "Ekip Faturası",
"team_billing_description": "Ekibiniz için faturalandırmayı yönetin", "team_billing_description": "Ekibiniz için faturalandırmayı yönetin",
"upgrade_to_flexible_pro_title": "Ekipler için faturayı değiştirdik", "upgrade_to_flexible_pro_title": "Ekipler için faturayı değiştirdik",
@@ -766,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}}, bir Huddle01 web3 görüntülü toplantı URL'si sağlayacaktır.", "cal_provide_huddle01_meeting_url": "{{appName}}, bir Huddle01 web3 görüntülü toplantı URL'si sağlayacaktır.",
"cal_provide_teams_meeting_url": "{{appName}}, bir MS Teams toplantı URL'si sağlayacaktır. NOT: İŞ VEYA OKUL HESABINIZIN OLMASI GEREKİR", "cal_provide_teams_meeting_url": "{{appName}}, bir MS Teams toplantı URL'si sağlayacaktır. NOT: İŞ VEYA OKUL HESABINIZIN OLMASI GEREKİR",
"require_payment": "Ödemeyi Gerekli Kılın", "require_payment": "Ödemeyi Gerekli Kılın",
"you_need_to_add_a_name": "Bir ad eklemeniz gerekiyor",
"commission_per_transaction": "işlem başına komisyon", "commission_per_transaction": "işlem başına komisyon",
"event_type_updated_successfully_description": "Etkinlik türünüz başarıyla güncellendi.", "event_type_updated_successfully_description": "Etkinlik türünüz başarıyla güncellendi.",
"hide_event_type": "Etkinlik türünü gizle", "hide_event_type": "Etkinlik türünü gizle",
@@ -856,18 +865,25 @@
"installed_apps": "Yüklü Uygulamalar", "installed_apps": "Yüklü Uygulamalar",
"free_to_use_apps": "Ücretsiz", "free_to_use_apps": "Ücretsiz",
"no_category_apps": "{{category}} uygulaması yok", "no_category_apps": "{{category}} uygulaması yok",
"all_apps": "Tüm uygulamalar",
"no_category_apps_description_calendar": "Çifte rezervasyonları önlemek amacıyla çakışmaları kontrol etmek için bir takvim uygulaması ekleyin", "no_category_apps_description_calendar": "Çifte rezervasyonları önlemek amacıyla çakışmaları kontrol etmek için bir takvim uygulaması ekleyin",
"no_category_apps_description_conferencing": "Müşterilerinizle görüntülü aramalar yapmak için bir konferans uygulaması eklemeyi deneyin",
"no_category_apps_description_payment": "Müşterilerinizle aranızdaki işlemleri kolaylaştırmak için bir ödeme uygulaması ekleyin", "no_category_apps_description_payment": "Müşterilerinizle aranızdaki işlemleri kolaylaştırmak için bir ödeme uygulaması ekleyin",
"no_category_apps_description_analytics": "Rezervasyon sayfalarınız için bir analiz uygulaması ekleyin", "no_category_apps_description_analytics": "Rezervasyon sayfalarınız için bir analiz uygulaması ekleyin",
"no_category_apps_description_automation": "Kullanılacak otomasyon uygulamasını ekleyin", "no_category_apps_description_automation": "Kullanılacak otomasyon uygulamasını ekleyin",
"no_category_apps_description_other": "Her türlü işlemi yapmak için farklı bir uygulama ekleyin", "no_category_apps_description_other": "Her türlü işlemi yapmak için farklı bir uygulama ekleyin",
"no_category_apps_description_web3": "Rezervasyon sayfalarınız için bir web3 uygulaması ekleyin", "no_category_apps_description_web3": "Rezervasyon sayfalarınız için bir web3 uygulaması ekleyin",
"no_category_apps_description_messaging": "Özel bildirimler ve hatırlatıcılar ayarlamak için bir mesajlaşma uygulaması ekleyin",
"no_category_apps_description_crm": "Tanıştığınız kullanıcıları takip etmek için bir CRM uygulaması ekleyin",
"installed_app_calendar_description": "Çifte rezervasyonları önlemek amacıyla çakışmaları kontrol etmek için takvimleri ayarlayın.", "installed_app_calendar_description": "Çifte rezervasyonları önlemek amacıyla çakışmaları kontrol etmek için takvimleri ayarlayın.",
"installed_app_payment_description": "Müşterilerinizden ücret alırken hangi ödeme işleme hizmetlerinin kullanılacağını yapılandırın.", "installed_app_payment_description": "Müşterilerinizden ücret alırken hangi ödeme işleme hizmetlerinin kullanılacağını yapılandırın.",
"installed_app_analytics_description": "Rezervasyon sayfalarınız için hangi analiz uygulamalarını kullanacağınızı yapılandırın", "installed_app_analytics_description": "Rezervasyon sayfalarınız için hangi analiz uygulamalarını kullanacağınızı yapılandırın",
"installed_app_other_description": "Diğer kategorilerdeki tüm yüklü uygulamalarınız.", "installed_app_other_description": "Diğer kategorilerdeki tüm yüklü uygulamalarınız.",
"installed_app_conferencing_description": "Hangi konferans uygulamalarının kullanılacağını belirleyin",
"installed_app_automation_description": "Kullanılacak otomasyon uygulamalarını yapılandırın", "installed_app_automation_description": "Kullanılacak otomasyon uygulamalarını yapılandırın",
"installed_app_web3_description": "Rezervasyon sayfalarınız için hangi web3 uygulamalarının kullanılacağını yapılandırın", "installed_app_web3_description": "Rezervasyon sayfalarınız için hangi web3 uygulamalarının kullanılacağını yapılandırın",
"installed_app_messaging_description": "Özel bildirimleri ve hatırlatıcıları ayarlamak için hangi mesajlaşma uygulamalarının kullanılacağını belirleyin",
"installed_app_crm_description": "Tanıştığınız kullanıcıları takip etmek için hangi CRM uygulamalarının kullanılacağını belirleyin",
"analytics": "Analizler", "analytics": "Analizler",
"empty_installed_apps_headline": "Yüklü uygulama yok", "empty_installed_apps_headline": "Yüklü uygulama yok",
"empty_installed_apps_description": "Uygulamalar, iş akışınızı iyileştirmenize ve planlama sürecinizi önemli ölçüde geliştirmenize olanak tanır.", "empty_installed_apps_description": "Uygulamalar, iş akışınızı iyileştirmenize ve planlama sürecinizi önemli ölçüde geliştirmenize olanak tanır.",
@@ -893,6 +909,7 @@
"create_events_on": "Şurada etkinlik oluşturun:", "create_events_on": "Şurada etkinlik oluşturun:",
"enterprise_license": "Bu bir kurumsal özelliktir", "enterprise_license": "Bu bir kurumsal özelliktir",
"enterprise_license_description": "Bu özelliği etkinleştirmek için {{consoleUrl}} konsolundan bir dağıtım anahtarı alın ve bunu .env dosyanıza CALCOM_LICENSE_KEY olarak ekleyin. Ekibinizin zaten bir lisansı varsa yardım için lütfen {{supportMail}} adresinden iletişime geçin.", "enterprise_license_description": "Bu özelliği etkinleştirmek için {{consoleUrl}} konsolundan bir dağıtım anahtarı alın ve bunu .env dosyanıza CALCOM_LICENSE_KEY olarak ekleyin. Ekibinizin zaten bir lisansı varsa yardım için lütfen {{supportMail}} adresinden iletişime geçin.",
"enterprise_license_development": "Bu özelliği geliştirme modunda deneyebilirsiniz. Üretim kullanımı için bir yöneticinin <2>yetkilendirme/kurulum</2> seçeneklerine giderek ve bir lisans anahtarı girmesi gerekir.",
"missing_license": "Eksik Lisans", "missing_license": "Eksik Lisans",
"signup_requires": "Ticari lisans gerekli", "signup_requires": "Ticari lisans gerekli",
"signup_requires_description": "{{companyName}} şu anda kayıt sayfasının ücretsiz, açık kaynaklı bir sürümünü sunmamaktadır. Kayıt bileşenlerine tam erişim elde etmek için ticari bir lisans almanız gerekiyor. Kişisel kullanım için hesap oluşturmak üzere Prisma Data veya başka bir Postgres arayüzü öneriyoruz.", "signup_requires_description": "{{companyName}} şu anda kayıt sayfasının ücretsiz, açık kaynaklı bir sürümünü sunmamaktadır. Kayıt bileşenlerine tam erişim elde etmek için ticari bir lisans almanız gerekiyor. Kişisel kullanım için hesap oluşturmak üzere Prisma Data veya başka bir Postgres arayüzü öneriyoruz.",
@@ -962,6 +979,7 @@
"confirm_delete_api_key": "Bu API anahtarını iptal et", "confirm_delete_api_key": "Bu API anahtarını iptal et",
"revoke_api_key": "API anahtarını iptal et", "revoke_api_key": "API anahtarını iptal et",
"api_key_copied": "API anahtarı kopyalandı!", "api_key_copied": "API anahtarı kopyalandı!",
"api_key_expires_on": "API anahtarının süresi şu tarihte dolacak:",
"delete_api_key_confirm_title": "Bu API anahtarı hesabınızdan kalıcı olarak kaldırılsın mı?", "delete_api_key_confirm_title": "Bu API anahtarı hesabınızdan kalıcı olarak kaldırılsın mı?",
"copy": "Kopyala", "copy": "Kopyala",
"expire_date": "Son tarih", "expire_date": "Son tarih",
@@ -984,6 +1002,9 @@
"user_impersonation_heading": "Kullanıcı Kimliğine Bürünme", "user_impersonation_heading": "Kullanıcı Kimliğine Bürünme",
"user_impersonation_description": "Bize bildirdiğiniz hataları hızlı bir şekilde çözmek için destek ekibimizin sizin adınıza geçici olarak oturum açmasına izin verir.", "user_impersonation_description": "Bize bildirdiğiniz hataları hızlı bir şekilde çözmek için destek ekibimizin sizin adınıza geçici olarak oturum açmasına izin verir.",
"team_impersonation_description": "Ekip üyelerinizin sizin adınıza geçici olarak oturum açmasına izin verir.", "team_impersonation_description": "Ekip üyelerinizin sizin adınıza geçici olarak oturum açmasına izin verir.",
"make_team_private": "Ekibi özel yap",
"make_team_private_description": "Bu özellik açıldığında ekip üyeleriniz diğer ekip üyelerini göremez.",
"you_cannot_see_team_members": "Özel bir ekibin tüm ekip üyelerini göremezsiniz.",
"allow_booker_to_select_duration": "Rezervasyon yapan kişinin süreyi seçmesine izin ver", "allow_booker_to_select_duration": "Rezervasyon yapan kişinin süreyi seçmesine izin ver",
"impersonate_user_tip": "Bu özelliğin tüm kullanımları denetlenir.", "impersonate_user_tip": "Bu özelliğin tüm kullanımları denetlenir.",
"impersonating_user_warning": "\"{{user}}\" kullanıcı adı kimliğine bürünme.", "impersonating_user_warning": "\"{{user}}\" kullanıcı adı kimliğine bürünme.",
@@ -1051,16 +1072,21 @@
"event_location": "Etkinliğin konumu", "event_location": "Etkinliğin konumu",
"reschedule_optional": "Yeniden planlama nedeni (isteğe bağlı)", "reschedule_optional": "Yeniden planlama nedeni (isteğe bağlı)",
"reschedule_placeholder": "Neden yeniden planlama ihtiyacı duyduğunuzu diğer kişilere bildirin", "reschedule_placeholder": "Neden yeniden planlama ihtiyacı duyduğunuzu diğer kişilere bildirin",
"event_cancelled": "Bu etkinlik iptal edildi",
"emailed_information_about_cancelled_event": "Sizi ve diğer katılımcıları bilgilendirmek için bir e-posta gönderdik.", "emailed_information_about_cancelled_event": "Sizi ve diğer katılımcıları bilgilendirmek için bir e-posta gönderdik.",
"this_input_will_shown_booking_this_event": "Bu girdi, bu etkinlik için rezervasyon yapılırken gösterilecek", "this_input_will_shown_booking_this_event": "Bu girdi, bu etkinlik için rezervasyon yapılırken gösterilecek",
"meeting_url_in_conformation_email": "Toplantı URL'si onay e-postasında mevcut", "meeting_url_in_conformation_email": "Toplantı URL'si onay e-postasında mevcut",
"url_start_with_https": "URL'nin http:// veya https:// ile başlaması gerekiyor", "url_start_with_https": "URL'nin http:// veya https:// ile başlaması gerekiyor",
"number_provided": "Telefon numarası sağlanacaktır", "number_provided": "Telefon numarası sağlanacaktır",
"before_event_trigger": "etkinlik başlamadan önce", "before_event_trigger": "etkinlik başlamadan önce",
"event_cancelled_trigger": "etkinlik iptal edildiğinde",
"new_event_trigger": "yeni bir etkinlik için rezervasyon yapıldığında", "new_event_trigger": "yeni bir etkinlik için rezervasyon yapıldığında",
"email_host_action": "organizatöre e-posta gönder", "email_host_action": "organizatöre e-posta gönder",
"email_attendee_action": "katılımcılara e-posta gönder", "email_attendee_action": "katılımcılara e-posta gönder",
"sms_attendee_action": "Katılımcıya SMS gönder",
"sms_number_action": "belirli bir numaraya SMS gönder", "sms_number_action": "belirli bir numaraya SMS gönder",
"whatsapp_number_action": "belirli bir numaraya Whatsapp mesajı gönder",
"whatsapp_attendee_action": "katılımcıya Whatsapp mesajı gönder",
"workflows": "İş akışları", "workflows": "İş akışları",
"new_workflow_btn": "Yeni İş Akışı", "new_workflow_btn": "Yeni İş Akışı",
"add_new_workflow": "Yeni iş akışı ekle", "add_new_workflow": "Yeni iş akışı ekle",
@@ -1124,6 +1150,8 @@
"choose_template": "Bir şablon seçin", "choose_template": "Bir şablon seçin",
"custom": "Özel", "custom": "Özel",
"reminder": "Hatırlatıcı", "reminder": "Hatırlatıcı",
"rescheduled": "Yeniden planlandı",
"completed": "Tamamlandı",
"reminder_email": "Hatırlatma: {{date}} tarihinde {{name}} ile {{eventType}}", "reminder_email": "Hatırlatma: {{date}} tarihinde {{name}} ile {{eventType}}",
"not_triggering_existing_bookings": "Etkinlik rezervasyonu yapılırken kullanıcıdan bir telefon numarası belirtmesi isteneceğinden mevcut rezervasyonlar için etkinleştirilmeyecektir.", "not_triggering_existing_bookings": "Etkinlik rezervasyonu yapılırken kullanıcıdan bir telefon numarası belirtmesi isteneceğinden mevcut rezervasyonlar için etkinleştirilmeyecektir.",
"minute_one": "{{count}} dakika", "minute_one": "{{count}} dakika",
@@ -1221,6 +1249,7 @@
"start_of_week": "Haftanın başlangıcı", "start_of_week": "Haftanın başlangıcı",
"recordings_title": "Kayıtlar", "recordings_title": "Kayıtlar",
"recording": "Kayıt", "recording": "Kayıt",
"happy_scheduling": "İyi planlamalar",
"select_calendars": "Çifte rezervasyonu önlemek için çakışmaları kontrol etmek istediğiniz takvimleri seçin.", "select_calendars": "Çifte rezervasyonu önlemek için çakışmaları kontrol etmek istediğiniz takvimleri seçin.",
"check_for_conflicts": "Çakışmaları kontrol edin", "check_for_conflicts": "Çakışmaları kontrol edin",
"view_recordings": "Kayıtları görüntüle", "view_recordings": "Kayıtları görüntüle",
@@ -1262,6 +1291,7 @@
"conferencing_description": "Toplantılarınız için favori video konferans uygulamalarınızı yönetin", "conferencing_description": "Toplantılarınız için favori video konferans uygulamalarınızı yönetin",
"add_conferencing_app": "Konferans Uygulaması ekle", "add_conferencing_app": "Konferans Uygulaması ekle",
"password_description": "Hesap şifreleriniz için ayarları yönetin", "password_description": "Hesap şifreleriniz için ayarları yönetin",
"set_up_two_factor_authentication": "İki Faktörlü Kimlik Doğrulamanızı ayarlayın",
"we_just_need_basic_info": "Profil kurulumunuzu almak için sadece bazı temel bilgilere ihtiyacımız var.", "we_just_need_basic_info": "Profil kurulumunuzu almak için sadece bazı temel bilgilere ihtiyacımız var.",
"skip": "Atla", "skip": "Atla",
"do_this_later": "Bunu daha sonra yap", "do_this_later": "Bunu daha sonra yap",
@@ -1275,6 +1305,8 @@
"connect_analytics_apps": "Analiz uygulamaları bağlayın", "connect_analytics_apps": "Analiz uygulamaları bağlayın",
"connect_other_apps": "Diğer uygulamaları bağlayın", "connect_other_apps": "Diğer uygulamaları bağlayın",
"connect_web3_apps": "Web3 uygulamalarını bağlayın", "connect_web3_apps": "Web3 uygulamalarını bağlayın",
"connect_messaging_apps": "Mesajlaşma uygulamalarını bağlayın",
"connect_crm_apps": "CRM uygulamalarını bağlayın",
"current_step_of_total": "{{currentStep}} / {{maxSteps}}. Adım", "current_step_of_total": "{{currentStep}} / {{maxSteps}}. Adım",
"add_variable": "Değişken ekle", "add_variable": "Değişken ekle",
"custom_phone_number": "Özel telefon numarası", "custom_phone_number": "Özel telefon numarası",
@@ -1287,12 +1319,14 @@
"location_info": "Etkinlik yeri", "location_info": "Etkinlik yeri",
"additional_notes_info": "Ek rezervasyon notları", "additional_notes_info": "Ek rezervasyon notları",
"attendee_name_info": "Rezervasyon yaptıran kişinin adı", "attendee_name_info": "Rezervasyon yaptıran kişinin adı",
"organizer_name_info": "Düzenleyenin adı",
"to": "Kime", "to": "Kime",
"workflow_turned_on_successfully": "{{workflowName}} iş akışı başarıyla {{offOn}} hale getirildi", "workflow_turned_on_successfully": "{{workflowName}} iş akışı başarıyla {{offOn}} hale getirildi",
"download_responses": "Yanıtları İndir", "download_responses": "Yanıtları İndir",
"download_responses_description": "Formunuza gelen tüm yanıtları CSV formatında indirin.", "download_responses_description": "Formunuza gelen tüm yanıtları CSV formatında indirin.",
"download": "İndir", "download": "İndir",
"download_recording": "Kaydı İndir", "download_recording": "Kaydı İndir",
"recording_from_your_recent_call": "{{appName}} uygulamasındaki son aramanızın kaydı indirilmeye hazır",
"create_your_first_form": "İlk formunuzu oluşturun", "create_your_first_form": "İlk formunuzu oluşturun",
"create_your_first_form_description": "Yönlendirme Formları ile yeterlik soruları sorabilir ve bunları doğru kişiye veya etkinlik türüne yönlendirebilirsiniz.", "create_your_first_form_description": "Yönlendirme Formları ile yeterlik soruları sorabilir ve bunları doğru kişiye veya etkinlik türüne yönlendirebilirsiniz.",
"create_your_first_webhook": "İlk Web kancanızı oluşturun", "create_your_first_webhook": "İlk Web kancanızı oluşturun",
@@ -1301,7 +1335,9 @@
"event_one": "etkinlik", "event_one": "etkinlik",
"event_other": "etkinlik", "event_other": "etkinlik",
"profile_team_description": "Ekip profiliniz için ayarları yönetin", "profile_team_description": "Ekip profiliniz için ayarları yönetin",
"profile_org_description": "Kuruluş profiliniz için ayarları yönetin",
"members_team_description": "Gruptaki kullanıcılar", "members_team_description": "Gruptaki kullanıcılar",
"organization_description": "Kuruluşunuzdaki yöneticileri ve üyeleri yönetin",
"team_url": "Ekip URL'si", "team_url": "Ekip URL'si",
"team_members": "Ekip üyeleri", "team_members": "Ekip üyeleri",
"more": "Daha fazla", "more": "Daha fazla",
@@ -1342,6 +1378,7 @@
"routing_forms_send_email_owner": "Sahibine E-posta Gönderin", "routing_forms_send_email_owner": "Sahibine E-posta Gönderin",
"routing_forms_send_email_owner_description": "Form gönderildiğinde sahibine bir e-posta gönderir", "routing_forms_send_email_owner_description": "Form gönderildiğinde sahibine bir e-posta gönderir",
"add_new_form": "Yeni form ekle", "add_new_form": "Yeni form ekle",
"add_new_team_form": "Ekibinize yeni bir form ekleyin",
"create_your_first_route": "İlk yönlendirmenizi oluşturun", "create_your_first_route": "İlk yönlendirmenizi oluşturun",
"route_to_the_right_person": "Formunuza verilen yanıtlara göre doğru kişiye yönlendirin", "route_to_the_right_person": "Formunuza verilen yanıtlara göre doğru kişiye yönlendirin",
"form_description": "Rezervasyon yapan kişiyi yönlendirmek için formunuzu oluşturun", "form_description": "Rezervasyon yapan kişiyi yönlendirmek için formunuzu oluşturun",
@@ -1446,6 +1483,7 @@
"yearly": "Yıllık", "yearly": "Yıllık",
"checkout": "Ödeme yap", "checkout": "Ödeme yap",
"your_team_disbanded_successfully": "Ekibiniz başarıyla dağıtıldı", "your_team_disbanded_successfully": "Ekibiniz başarıyla dağıtıldı",
"your_org_disbanded_successfully": "Kuruluşunuz başarıyla dağıtıldı",
"error_creating_team": "Ekip oluşturulurken bir hata oluştu", "error_creating_team": "Ekip oluşturulurken bir hata oluştu",
"you": "Siz", "you": "Siz",
"resend_email": "E-postayı tekrar gönder", "resend_email": "E-postayı tekrar gönder",
@@ -1455,6 +1493,7 @@
"must_enter_team_name": "Ekip adı girilmelidir", "must_enter_team_name": "Ekip adı girilmelidir",
"team_url_required": "Ekip URL'si girilmelidir", "team_url_required": "Ekip URL'si girilmelidir",
"url_taken": "Bu URL zaten kullanılıyor", "url_taken": "Bu URL zaten kullanılıyor",
"problem_registering_domain": "Alt alan adı kaydıyla ilgili bir sorun oluştu, lütfen tekrar deneyin veya bir yöneticiyle iletişime geçin",
"team_publish": "Ekibi yayınla", "team_publish": "Ekibi yayınla",
"number_text_notifications": "Telefon numarası (SMS bildirimleri)", "number_text_notifications": "Telefon numarası (SMS bildirimleri)",
"attendee_email_variable": "Katılımcı e-postası", "attendee_email_variable": "Katılımcı e-postası",
@@ -1479,6 +1518,7 @@
"find_the_best_person": "Mevcut en iyi kişiyi bulun ve ekip üyeleriniz arasında rotasyon yapın.", "find_the_best_person": "Mevcut en iyi kişiyi bulun ve ekip üyeleriniz arasında rotasyon yapın.",
"fixed_round_robin": "Sabit döngü", "fixed_round_robin": "Sabit döngü",
"add_one_fixed_attendee": "Bir sabit katılımcı ekleyin ve katılımcı sayısına göre rotasyon yapın.", "add_one_fixed_attendee": "Bir sabit katılımcı ekleyin ve katılımcı sayısına göre rotasyon yapın.",
"calcom_is_better_with_team": "{{appName}}, ekiplerle daha iyidir",
"the_calcom_team": "{{companyName}} ekibi", "the_calcom_team": "{{companyName}} ekibi",
"add_your_team_members": "Ekip üyelerinizi etkinlik türlerinize ekleyin. Herkesi eklemek için toplu planlamayı kullanın veya döngüsel planlama ile en uygun kişiyi bulun.", "add_your_team_members": "Ekip üyelerinizi etkinlik türlerinize ekleyin. Herkesi eklemek için toplu planlamayı kullanın veya döngüsel planlama ile en uygun kişiyi bulun.",
"booking_limit_reached": "Bu etkinlik türü için Rezervasyon Sınırına ulaşıldı", "booking_limit_reached": "Bu etkinlik türü için Rezervasyon Sınırına ulaşıldı",
@@ -1498,6 +1538,7 @@
"navigate_installed_apps": "Yüklü uygulamalara git", "navigate_installed_apps": "Yüklü uygulamalara git",
"disabled_calendar": "Yüklü başka bir takviminiz varsa yeni randevular bu takvime eklenir. Aksi takdirde yeni bir takvim bağlamazsanız yeni rezervasyonları kaçırabilirsiniz.", "disabled_calendar": "Yüklü başka bir takviminiz varsa yeni randevular bu takvime eklenir. Aksi takdirde yeni bir takvim bağlamazsanız yeni rezervasyonları kaçırabilirsiniz.",
"enable_apps": "Uygulamaları Etkinleştir", "enable_apps": "Uygulamaları Etkinleştir",
"enable_apps_description": "Kullanıcıların {{appName}} ile entegre edebileceği uygulamaları etkinleştirin",
"purchase_license": "Lisans satın alın", "purchase_license": "Lisans satın alın",
"already_have_key": "Zaten bir anahtarım var:", "already_have_key": "Zaten bir anahtarım var:",
"already_have_key_suggestion": "Lütfen mevcut CALCOM_LICENSE_KEY ortam değişkeninizi buraya kopyalayın.", "already_have_key_suggestion": "Lütfen mevcut CALCOM_LICENSE_KEY ortam değişkeninizi buraya kopyalayın.",
@@ -1617,7 +1658,10 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} yapılandırmasını silmek istediğinizden emin misiniz? {{connectionType}} girişini kullanan ekip üyeleriniz artık Cal.com'a erişemeyecek.", "delete_sso_configuration_confirmation_description": "{{connectionType}} yapılandırmasını silmek istediğinizden emin misiniz? {{connectionType}} girişini kullanan ekip üyeleriniz artık Cal.com'a erişemeyecek.",
"organizer_timezone": "Organizatörün saat dilimi", "organizer_timezone": "Organizatörün saat dilimi",
"email_user_cta": "Daveti görüntüle", "email_user_cta": "Daveti görüntüle",
"email_no_user_invite_heading": "{{appName}} {{entity}} uygulamasına katılmaya davet edildiniz",
"email_no_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} ekibine katılmaya davet etti. {{appName}}, size ve ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.", "email_no_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} ekibine katılmaya davet etti. {{appName}}, size ve ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.",
"email_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} uygulamasındaki {{entity}} `{{teamName}}` ekibine katılmaya davet etti. {{appName}}, size ve {{entity}} ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.",
"email_no_user_invite_steps_intro": "{{entity}} ekibinizle birlikte kısa sürede ve sorunsuz planlama yapmanın keyfini çıkarmanız için birkaç adımda size rehberlik edeceğiz.",
"email_no_user_step_one": "Kullanıcı adınızı seçin", "email_no_user_step_one": "Kullanıcı adınızı seçin",
"email_no_user_step_two": "Takvim hesabınızı bağlayın", "email_no_user_step_two": "Takvim hesabınızı bağlayın",
"email_no_user_step_three": "Müsaitlik durumunuzu ayarlayın", "email_no_user_step_three": "Müsaitlik durumunuzu ayarlayın",
@@ -1628,6 +1672,7 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "İş akışı yok", "no_workflows": "İş akışı yok",
"change_filter": "Kişisel ve ekip iş akışlarınızı görmek için filtreyi değiştirin.", "change_filter": "Kişisel ve ekip iş akışlarınızı görmek için filtreyi değiştirin.",
"change_filter_common": "Sonuçları görmek için filtreyi değiştirin.",
"no_results_for_filter": "Filtre için hiçbir sonuç bulunamadı", "no_results_for_filter": "Filtre için hiçbir sonuç bulunamadı",
"recommended_next_steps": "Önerilen sonraki adımlar", "recommended_next_steps": "Önerilen sonraki adımlar",
"create_a_managed_event": "Yönetilen bir olay türü oluşturun", "create_a_managed_event": "Yönetilen bir olay türü oluşturun",
@@ -1641,6 +1686,7 @@
"attendee_no_longer_attending": "Bir katılımcı artık etkinliğinize katılmıyor", "attendee_no_longer_attending": "Bir katılımcı artık etkinliğinize katılmıyor",
"attendee_no_longer_attending_subtitle": "{{name}} etkinlik katılımını iptal etti. Bu, bu zaman aralığı için bir yerin açıldığı anlamına gelir", "attendee_no_longer_attending_subtitle": "{{name}} etkinlik katılımını iptal etti. Bu, bu zaman aralığı için bir yerin açıldığı anlamına gelir",
"create_event_on": "Şu tarih için etkinlik oluşturun:", "create_event_on": "Şu tarih için etkinlik oluşturun:",
"create_routing_form_on": "Şurası için yönlendirme formu oluştur:",
"default_app_link_title": "Varsayılan uygulama bağlantısını ayarlayın", "default_app_link_title": "Varsayılan uygulama bağlantısını ayarlayın",
"default_app_link_description": "Varsayılan uygulama bağlantısını ayarlamak, yeni oluşturulan tüm etkinlik türlerinin ayarladığınız uygulama bağlantısını kullanmasına olanak tanır.", "default_app_link_description": "Varsayılan uygulama bağlantısını ayarlamak, yeni oluşturulan tüm etkinlik türlerinin ayarladığınız uygulama bağlantısını kullanmasına olanak tanır.",
"organizer_default_conferencing_app": "Organizatörün varsayılan uygulaması", "organizer_default_conferencing_app": "Organizatörün varsayılan uygulaması",
@@ -1650,6 +1696,7 @@
"booking_questions_title": "Rezervasyon soruları", "booking_questions_title": "Rezervasyon soruları",
"booking_questions_description": "Rezervasyon sayfasında sorulan soruları özelleştirin", "booking_questions_description": "Rezervasyon sayfasında sorulan soruları özelleştirin",
"add_a_booking_question": "Soru ekle", "add_a_booking_question": "Soru ekle",
"identifier": "Tanımlayıcı",
"duplicate_email": "E-posta yinelenmiş", "duplicate_email": "E-posta yinelenmiş",
"booking_with_payment_cancelled": "Artık bu etkinlik için ödeme yapılamıyor", "booking_with_payment_cancelled": "Artık bu etkinlik için ödeme yapılamıyor",
"booking_with_payment_cancelled_already_paid": "Bu rezervasyon ödemesi için iade yolda.", "booking_with_payment_cancelled_already_paid": "Bu rezervasyon ödemesi için iade yolda.",
@@ -1660,6 +1707,7 @@
"show_on_booking_page": "Rezervasyon sayfasında göster", "show_on_booking_page": "Rezervasyon sayfasında göster",
"get_started_zapier_templates": "Zapier şablonlarını kullanmaya başlayın", "get_started_zapier_templates": "Zapier şablonlarını kullanmaya başlayın",
"team_is_unpublished": "{{team}} paylaşılmadı", "team_is_unpublished": "{{team}} paylaşılmadı",
"team_is_unpublished_description": "Bu {{entity}} bağlantısı şu anda kullanılamıyor. Lütfen {{entity}} sahibiyle iletişime geçin veya ondan bir bağlantı paylaşmasını isteyin.",
"team_member": "Ekip üyesi", "team_member": "Ekip üyesi",
"a_routing_form": "Yönlendirme Formu", "a_routing_form": "Yönlendirme Formu",
"form_description_placeholder": "Form Açıklaması", "form_description_placeholder": "Form Açıklaması",
@@ -1689,6 +1737,7 @@
"spot_popular_event_types": "Popüler etkinlik türlerini tespit edin", "spot_popular_event_types": "Popüler etkinlik türlerini tespit edin",
"spot_popular_event_types_description": "Hangi etkinlik türünüzün en çok tıklandığını ve rezervasyon aldığını görün", "spot_popular_event_types_description": "Hangi etkinlik türünüzün en çok tıklandığını ve rezervasyon aldığını görün",
"no_responses_yet": "Henüz yanıt yok", "no_responses_yet": "Henüz yanıt yok",
"no_routes_defined": "Yönlendirmeler tanımlanmadı",
"this_will_be_the_placeholder": "Bu, yer tutucu olacak", "this_will_be_the_placeholder": "Bu, yer tutucu olacak",
"error_booking_event": "Etkinlik rezervasyonu yapılırken bir hata oluştu, lütfen sayfayı yenileyerek tekrar deneyin", "error_booking_event": "Etkinlik rezervasyonu yapılırken bir hata oluştu, lütfen sayfayı yenileyerek tekrar deneyin",
"timeslot_missing_title": "Zaman aralığı seçilmedi", "timeslot_missing_title": "Zaman aralığı seçilmedi",
@@ -1697,6 +1746,7 @@
"switch_monthly": "Aylık görünüme geç", "switch_monthly": "Aylık görünüme geç",
"switch_weekly": "Haftalık görünüme geç", "switch_weekly": "Haftalık görünüme geç",
"switch_multiday": "Gün görünümüne geç", "switch_multiday": "Gün görünümüne geç",
"switch_columnview": "Sütun görünümüne geç",
"num_locations": "{{num}} konum seçeneği", "num_locations": "{{num}} konum seçeneği",
"select_on_next_step": "Bir sonraki adımda seç", "select_on_next_step": "Bir sonraki adımda seç",
"this_meeting_has_not_started_yet": "Bu toplantı henüz başlamadı", "this_meeting_has_not_started_yet": "Bu toplantı henüz başlamadı",
@@ -1735,6 +1785,7 @@
"managed_event_dialog_title_one": "URL /{{slug}}, {{count}} üye için zaten mevcut. Bunu değiştirmek istiyor musunuz?", "managed_event_dialog_title_one": "URL /{{slug}}, {{count}} üye için zaten mevcut. Bunu değiştirmek istiyor musunuz?",
"managed_event_dialog_title_other": "URL /{{slug}}, {{count}} üye için zaten mevcut. Bunu değiştirmek istiyor musunuz?", "managed_event_dialog_title_other": "URL /{{slug}}, {{count}} üye için zaten mevcut. Bunu değiştirmek istiyor musunuz?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> zaten <strong>/{{slug}}</strong> URL'sini kullanıyor.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> zaten <strong>/{{slug}}</strong> URL'sini kullanıyor.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> zaten <strong>/{{slug}}</strong> URL'sini kullanıyor.",
"managed_event_dialog_clarification": "Değiştirmeyi seçmeniz durumunda onları bilgilendiririz. Üzerine yazmak istemiyorsanız geri dönerek onları kaldırın.", "managed_event_dialog_clarification": "Değiştirmeyi seçmeniz durumunda onları bilgilendiririz. Üzerine yazmak istemiyorsanız geri dönerek onları kaldırın.",
"review_event_type": "Etkinlik Türünü inceleyin", "review_event_type": "Etkinlik Türünü inceleyin",
"looking_for_more_analytics": "Daha fazla analiz mi arıyorsunuz?", "looking_for_more_analytics": "Daha fazla analiz mi arıyorsunuz?",
@@ -1789,11 +1840,13 @@
"invite_link_copied": "Davet bağlantısı kopyalandı", "invite_link_copied": "Davet bağlantısı kopyalandı",
"invite_link_deleted": "Davet bağlantısı silindi", "invite_link_deleted": "Davet bağlantısı silindi",
"invite_link_updated": "Davet bağlantısı ayarları kaydedildi", "invite_link_updated": "Davet bağlantısı ayarları kaydedildi",
"link_expires_after": "Bağlantının sona erme süresi ayarlandı...",
"one_day": "1 gün", "one_day": "1 gün",
"seven_days": "7 gün", "seven_days": "7 gün",
"thirty_days": "30 gün", "thirty_days": "30 gün",
"three_months": "3 ay", "three_months": "3 ay",
"one_year": "1 yıl", "one_year": "1 yıl",
"team_invite_received": "{{teamName}} ekibine katılmaya davet edildiniz",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Katılımcıdan {{amount, currency}} tahsil etmek üzeresiniz. Devam etmek istediğinizden emin misiniz?", "charge_card_dialog_body": "Katılımcıdan {{amount, currency}} tahsil etmek üzeresiniz. Devam etmek istediğinizden emin misiniz?",
"charge_attendee": "Katılımcıdan {{amount, currency}} tahsil edin", "charge_attendee": "Katılımcıdan {{amount, currency}} tahsil edin",
@@ -1802,6 +1855,7 @@
"email_invite_team_bulk": "{{userCount}} kullanıcı davet edildi", "email_invite_team_bulk": "{{userCount}} kullanıcı davet edildi",
"error_collecting_card": "Kart bilgileri alınırken hata oluştu", "error_collecting_card": "Kart bilgileri alınırken hata oluştu",
"image_size_limit_exceed": "Yüklenen resim boyutu 5 MB boyut limitini aşmamalıdır", "image_size_limit_exceed": "Yüklenen resim boyutu 5 MB boyut limitini aşmamalıdır",
"unauthorized_workflow_error_message": "{{errorCode}}: Bu iş akışını etkinleştirme veya devre dışı bırakma yetkiniz yok",
"inline_embed": "Satır İçine Yerleştir", "inline_embed": "Satır İçine Yerleştir",
"load_inline_content": "Etkinlik türünüzü doğrudan diğer web sitesi içeriğinizle birlikte yükler.", "load_inline_content": "Etkinlik türünüzü doğrudan diğer web sitesi içeriğinizle birlikte yükler.",
"floating_pop_up_button": "Kayan açılır düğme", "floating_pop_up_button": "Kayan açılır düğme",
@@ -1821,8 +1875,13 @@
"connect_google_workspace": "Google Workspace'i bağlayın", "connect_google_workspace": "Google Workspace'i bağlayın",
"google_workspace_admin_tooltip": "Bu özelliği kullanmak için Çalışma Alanı Yöneticisi olmalısınız", "google_workspace_admin_tooltip": "Bu özelliği kullanmak için Çalışma Alanı Yöneticisi olmalısınız",
"first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun", "first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun",
"install_app_on": "Uygulamayı şuraya yükle:",
"create_for": "Oluşturun", "create_for": "Oluşturun",
"setup_organization": "Bir Kuruluş Oluşturun",
"organization_banner_description": "Ekiplerinizin, döngüsel ve toplu planlama ile paylaşılan uygulamalar, iş akışları ve olay türleri oluşturabileceği bir ortam oluşturun.",
"organization_banner_title": "Kuruluşları birden çok ekiple yönetin",
"set_up_your_organization": "Kuruluşunuzu düzenleyin", "set_up_your_organization": "Kuruluşunuzu düzenleyin",
"organizations_description": "Kuruluşlar, ekiplerin paylaşımlı etkinlik türleri, uygulamalar, iş akışları ve daha fazlasını oluşturabileceği paylaşımlı ortamlardır.",
"must_enter_organization_name": "Bir kuruluş adı girilmelidir", "must_enter_organization_name": "Bir kuruluş adı girilmelidir",
"must_enter_organization_admin_email": "Kuruluşunuzun e-posta adresini girmelisiniz", "must_enter_organization_admin_email": "Kuruluşunuzun e-posta adresini girmelisiniz",
"admin_email": "Kuruluşunuzun e-posta adresi", "admin_email": "Kuruluşunuzun e-posta adresi",
@@ -1833,19 +1892,52 @@
"organization_verify_email_body": "Kuruluşunuzu düzenlemeye devam etmek ve e-posta adresinizi doğrulamak için lütfen aşağıdaki kodu kullanın.", "organization_verify_email_body": "Kuruluşunuzu düzenlemeye devam etmek ve e-posta adresinizi doğrulamak için lütfen aşağıdaki kodu kullanın.",
"additional_url_parameters": "Ek URL parametreleri", "additional_url_parameters": "Ek URL parametreleri",
"about_your_organization": "Kuruluşunuz hakkında", "about_your_organization": "Kuruluşunuz hakkında",
"about_your_organization_description": "Kuruluşlar; paylaşımlı üyeler, etkinlik türleri, uygulamalar, iş akışları ve daha fazlasıyla birden çok ekip oluşturabileceğiniz paylaşımlı ortamlardır.",
"create_your_teams": "Ekibinizi oluşuturun", "create_your_teams": "Ekibinizi oluşuturun",
"create_your_teams_description": "Ekip üyelerinizi kuruluşunuza ekleyerek planlama işlerinizi birlikte yapmaya başlayın",
"invite_organization_admins": "Kuruluşunuzun yöneticilerini davet edin", "invite_organization_admins": "Kuruluşunuzun yöneticilerini davet edin",
"invite_organization_admins_description": "Bu yöneticilerin kuruluşunuzdaki tüm ekiplere erişimi olacaktır. Ekip yöneticilerini ve üyeleri daha sonra ekleyebilirsiniz.",
"set_a_password": "Bir şifre belirleyin",
"set_a_password_description": "Kuruluşunuzun e-posta adresi ve bu şifre ile yeni bir kullanıcı hesabı oluşturulacaktır.",
"organization_logo": "Kuruluş Logosu",
"organization_about_description": "Birkaç cümleyle kuruluşunuzdan bahsedin. Bu, kuruluşunuzun herkese açık profil sayfasında görünecektir.",
"ill_do_this_later": "Bunu daha sonra yapacağım",
"verify_your_email": "E-posta adresinizi doğrulayın",
"enter_digit_code": "{{email}} adresine gönderdiğimiz 6 haneli kodu girin",
"verify_email_organization": "Bir kuruluş oluşturmak için e-postanızı doğrulayın",
"code_provided_invalid": "Sağlanan kod geçerli değil, tekrar deneyin",
"email_already_used": "E-posta zaten kullanılıyor",
"organization_admin_invited_heading": "{{orgName}} ekibine katılmaya davet edildiniz",
"organization_admin_invited_body": "{{orgName}} ekibine katılın ve toplantıları planlamaya değil, toplantılarınıza odaklanın!",
"duplicated_slugs_warning": "Aşağıdaki ekipler, yinelenen bilgi hataları nedeniyle oluşturulamadı: {{slugs}}",
"team_names_empty": "Ekip adları boş olamaz",
"team_names_repeated": "Takım adları tekrar edilemez",
"user_belongs_organization": "Kullanıcı bir kuruluşa ait",
"org_no_teams_yet": "Bu kuruluşun henüz ekibi yok",
"org_no_teams_yet_description": "Yöneticiyseniz, burada gösterilecek ekipler oluşturduğunuzdan emin olun.",
"set_up": "Düzenle",
"set_up_your_profile": "Profilinizi düzenleyin",
"set_up_your_profile_description": "{{orgName}}'deki kişilerin kim olduğunuzu ve herkese açık bir bağlantı aracılığıyla sizinle nasıl bağlantı kuracaklarını bilmelerini sağlayın.",
"my_profile": "Profilim", "my_profile": "Profilim",
"my_settings": "Ayarlarım", "my_settings": "Ayarlarım",
"crm": "CRM", "crm": "CRM",
"messaging": "Mesajlaşma", "messaging": "Mesajlaşma",
"sender_id_info": "SMS'i gönderen alanında gösterilen ad veya numara (bazı ülkeler alfasayısal gönderen kimliklerine izin vermez)",
"org_admins_can_create_new_teams": "Yalnızca kuruluşunuzun yöneticisi yeni ekipler oluşturabilir",
"google_new_spam_policy": "Google'ın yeni spam politikası nedeniyle bu rezervasyon için e-posta veya takvim bildirimleri alamayabilirsiniz.",
"resolve": "Çöz",
"no_organization_slug": "Bu kuruluş için ekipler oluşturulurken bir hata oluştu. URL bilgisi eksik.", "no_organization_slug": "Bu kuruluş için ekipler oluşturulurken bir hata oluştu. URL bilgisi eksik.",
"org_name": "Kuruluş adı", "org_name": "Kuruluş adı",
"org_url": "Kuruluş URL'si", "org_url": "Kuruluş URL'si",
"copy_link_org": "Bağlantıyı kuruluşa kopyala",
"404_the_org": "Kuruluş", "404_the_org": "Kuruluş",
"404_the_team": "Ekip", "404_the_team": "Ekip",
"404_claim_entity_org": "Kuruluşunuz için alt alan adınızı talep edin",
"404_claim_entity_team": "Bu ekibi sahiplenin ve planlamaları toplu şekilde yönetmeye başlayın",
"insights_all_org_filter": "Tümü", "insights_all_org_filter": "Tümü",
"insights_team_filter": "Ekip: {{teamName}}", "insights_team_filter": "Ekip: {{teamName}}",
"insights_user_filter": "Kullanıcı: {{userName}}", "insights_user_filter": "Kullanıcı: {{userName}}",
"custom_plan": "Özel Plan" "insights_subtitle": "Etkinlikleriniz için rezervasyon analizlerini görüntüleyin",
"custom_plan": "Özel Plan",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Yeni dizelerinizi yukarıya ekleyin ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+178 -1
View File
@@ -18,12 +18,16 @@
"verify_email_email_header": "Xác minh địa chỉ email của bạn", "verify_email_email_header": "Xác minh địa chỉ email của bạn",
"verify_email_email_button": "Xác minh email", "verify_email_email_button": "Xác minh email",
"verify_email_email_body": "Vui lòng xác minh địa chỉ email của bạn bằng cách nhấp vào nút bên dưới.", "verify_email_email_body": "Vui lòng xác minh địa chỉ email của bạn bằng cách nhấp vào nút bên dưới.",
"verify_email_email_link_text": "Đây là liên kết phòng trường hợp bạn không thích nhấp vào nút:",
"email_sent": "Email đã gửi thành công",
"event_declined_subject": "Đã từ chối: {{title}} tại {{date}}", "event_declined_subject": "Đã từ chối: {{title}} tại {{date}}",
"event_cancelled_subject": "Đã huỷ: {{title}} vào {{date}}", "event_cancelled_subject": "Đã huỷ: {{title}} vào {{date}}",
"event_request_declined": "Lời mời sự kiện của bạn đã bị từ chối", "event_request_declined": "Lời mời sự kiện của bạn đã bị từ chối",
"event_request_declined_recurring": "Lời mời sự kiện định kỳ của bạn đã bị từ chối", "event_request_declined_recurring": "Lời mời sự kiện định kỳ của bạn đã bị từ chối",
"event_request_cancelled": "Sự kiện của bạn đã bị huỷ",
"organizer": "Tổ chức", "organizer": "Tổ chức",
"need_to_reschedule_or_cancel": "Cần phải đổi lịch hẹn hoặc huỷ?", "need_to_reschedule_or_cancel": "Cần phải đổi lịch hẹn hoặc huỷ?",
"no_options_available": "Không tuỳ chọn nào khả dụng",
"cancellation_reason": "Lý do hủy", "cancellation_reason": "Lý do hủy",
"cancellation_reason_placeholder": "Lý do bạn muốn hủy?", "cancellation_reason_placeholder": "Lý do bạn muốn hủy?",
"rejection_reason": "Lý do từ chối", "rejection_reason": "Lý do từ chối",
@@ -83,7 +87,9 @@
"your_meeting_has_been_booked": "Cuộc họp của bạn đã được đặt", "your_meeting_has_been_booked": "Cuộc họp của bạn đã được đặt",
"event_type_has_been_rescheduled_on_time_date": "{{title}} của bạn đã được chuyển sang ngày {{date}}.", "event_type_has_been_rescheduled_on_time_date": "{{title}} của bạn đã được chuyển sang ngày {{date}}.",
"event_has_been_rescheduled": "Đã cập nhật - Sự kiện của bạn đã được đổi", "event_has_been_rescheduled": "Đã cập nhật - Sự kiện của bạn đã được đổi",
"request_reschedule_subtitle": "{{organizer}} đã huỷ đặt chỗ đó và yêu cầu bạn chọn thời gian khác.",
"request_reschedule_title_organizer": "Bạn đã yêu cầu {{attendee}} xếp lại lịch", "request_reschedule_title_organizer": "Bạn đã yêu cầu {{attendee}} xếp lại lịch",
"request_reschedule_subtitle_organizer": "Bạn đã huỷ mục đặt chỗ này và {{attendee}} nên chọn thời gian đặt chỗ mới với bạn.",
"rescheduled_event_type_subject": "Đã gửi yêu cầu xếp lại lịch: {{eventType}} với {{name}} lúc {{date}}", "rescheduled_event_type_subject": "Đã gửi yêu cầu xếp lại lịch: {{eventType}} với {{name}} lúc {{date}}",
"requested_to_reschedule_subject_attendee": "Thao tác cần làm để xếp lại lịch: Vui lòng đặt thời gian mới cho {{eventType}} với {{name}}", "requested_to_reschedule_subject_attendee": "Thao tác cần làm để xếp lại lịch: Vui lòng đặt thời gian mới cho {{eventType}} với {{name}}",
"hi_user_name": "Xin chào {{name}}", "hi_user_name": "Xin chào {{name}}",
@@ -124,6 +130,7 @@
"upgrade_banner_action": "Nâng cấp tại đây", "upgrade_banner_action": "Nâng cấp tại đây",
"team_upgraded_successfully": "Nhóm bạn đã được nâng cấp thành công!", "team_upgraded_successfully": "Nhóm bạn đã được nâng cấp thành công!",
"org_upgrade_banner_description": "Cám ơn bạn đã dùng thử gói Tổ chức. Chúng tôi để ý thấy Tổ chức \"{{teamName}}\" của bạn cần được nâng cấp.", "org_upgrade_banner_description": "Cám ơn bạn đã dùng thử gói Tổ chức. Chúng tôi để ý thấy Tổ chức \"{{teamName}}\" của bạn cần được nâng cấp.",
"org_upgraded_successfully": "Tổ chức của bạn đã được nâng cấp thành công!",
"use_link_to_reset_password": "Sử dụng đường link dưới đây để thay đổi mật khẩu của bạn", "use_link_to_reset_password": "Sử dụng đường link dưới đây để thay đổi mật khẩu của bạn",
"hey_there": "Xin chào,", "hey_there": "Xin chào,",
"forgot_your_password_calcom": "Quên mật khẩu của bạn? - {{appName}}", "forgot_your_password_calcom": "Quên mật khẩu của bạn? - {{appName}}",
@@ -190,6 +197,7 @@
"blog": "Blog", "blog": "Blog",
"blog_description": "Đọc tin tức và bài báo mới nhất của chúng tôi", "blog_description": "Đọc tin tức và bài báo mới nhất của chúng tôi",
"join_our_community": "Tham gia cộng đồng của chúng tôi", "join_our_community": "Tham gia cộng đồng của chúng tôi",
"join_our_discord": "Gia nhập Discord của chúng tôi",
"404_claim_entity_user": "Lấy tên người dùng của bạn và lên lịch sự kiện", "404_claim_entity_user": "Lấy tên người dùng của bạn và lên lịch sự kiện",
"popular_pages": "Các trang phổ biến", "popular_pages": "Các trang phổ biến",
"register_now": "Đăng ký ngay", "register_now": "Đăng ký ngay",
@@ -197,6 +205,7 @@
"page_doesnt_exist": "Trang này không tồn tại.", "page_doesnt_exist": "Trang này không tồn tại.",
"check_spelling_mistakes_or_go_back": "Kiểm tra lỗi chính tả hoặc quay lại trang trước.", "check_spelling_mistakes_or_go_back": "Kiểm tra lỗi chính tả hoặc quay lại trang trước.",
"404_page_not_found": "404: Không thể tìm thấy trang này.", "404_page_not_found": "404: Không thể tìm thấy trang này.",
"booker_event_not_found": "Chúng tôi không thể tìm thấy sự kiện mà bạn đang tìm cách đặt hẹn.",
"getting_started": "Bắt Đầu", "getting_started": "Bắt Đầu",
"15min_meeting": "Cuộc họp 15 phút", "15min_meeting": "Cuộc họp 15 phút",
"30min_meeting": "Cuộc họp 30 phút", "30min_meeting": "Cuộc họp 30 phút",
@@ -232,11 +241,14 @@
"done": "Xong", "done": "Xong",
"all_done": "Đã xong hết!", "all_done": "Đã xong hết!",
"all": "Tất cả", "all": "Tất cả",
"yours": "Tài khoản của bạn",
"available_apps": "Ứng dụng hiện có", "available_apps": "Ứng dụng hiện có",
"check_email_reset_password": "Kiểm tra hộp thư điện tử của bạn. Chúng tôi đã gửi cho bạn một liên kết để đặt lại mật khẩu của bạn.", "check_email_reset_password": "Kiểm tra hộp thư điện tử của bạn. Chúng tôi đã gửi cho bạn một liên kết để đặt lại mật khẩu của bạn.",
"finish": "Hoàn thành", "finish": "Hoàn thành",
"organization_general_description": "Quản lí cài đặt cho ngôn ngữ và múi giờ của nhóm bạn",
"few_sentences_about_yourself": "Vài câu về bản thân bạn - nó sẽ xuất hiện trên trang cá nhân của bạn.", "few_sentences_about_yourself": "Vài câu về bản thân bạn - nó sẽ xuất hiện trên trang cá nhân của bạn.",
"nearly_there": "Sắp xong rồi!", "nearly_there": "Sắp xong rồi!",
"nearly_there_instructions": "Điều cuối cùng, mô tả ngắn gọn về bạn và một bức ảnh để giúp bạn nhận lịch hẹn dễ hơn và cho mọi người biết họ đang đặt lịch hẹn với ai.",
"set_availability_instructions": "Xác định những phạm vi thời gian bạn có thể chấp nhận lịch hẹn định kỳ. Bạn có thể tạo thêm phạm vi thời gian này sau và gán chúng vào các lịch khác nhau.", "set_availability_instructions": "Xác định những phạm vi thời gian bạn có thể chấp nhận lịch hẹn định kỳ. Bạn có thể tạo thêm phạm vi thời gian này sau và gán chúng vào các lịch khác nhau.",
"set_availability": "Đặt lịch khả dụng của bạn", "set_availability": "Đặt lịch khả dụng của bạn",
"continue_without_calendar": "Tiếp tục mà không có lịch", "continue_without_calendar": "Tiếp tục mà không có lịch",
@@ -292,6 +304,18 @@
"success": "Thành công", "success": "Thành công",
"failed": "Thất bại", "failed": "Thất bại",
"password_has_been_reset_login": "Mật khẩu của bạn đã được thiết lập lại. Bây giờ bạn có thể đăng nhập bằng mật khẩu mới tạo của mình.", "password_has_been_reset_login": "Mật khẩu của bạn đã được thiết lập lại. Bây giờ bạn có thể đăng nhập bằng mật khẩu mới tạo của mình.",
"layout": "Bố trí",
"bookerlayout_default_title": "Giao diện mặc định",
"bookerlayout_description": "Bạn có thể chọn nhiều dạng và người đặt lịch hẹn có thể chuyển đổi qua lại các giao diện.",
"bookerlayout_user_settings_title": "Bố trí lịch hẹn",
"bookerlayout_user_settings_description": "Bạn có thể chọn nhiều dạng và người đặt lịch hẹn có thể chuyển đổi qua lại các giao diện. Dạng này có thể được thay thế tuỳ theo loại sự kiện.",
"bookerlayout_month_view": "Tháng",
"bookerlayout_week_view": "Hằng tuần",
"bookerlayout_column_view": "Cột",
"bookerlayout_error_min_one_enabled": "Ít nhất phải bật một bố trí.",
"bookerlayout_error_default_not_enabled": "Bố trí mà bạn chọn làm giao diện mặc định không phải là một phần của những bố trí đã bật.",
"bookerlayout_error_unknown_layout": "Bố trí mà bạn chọn không phải là bố trí hợp lệ.",
"bookerlayout_override_global_settings": "Bạn có thể quản lý cái này cho tất cả những loại sự kiện của bạn, trong phần <2>cài đặt / hiển thị</2> hoặc <6>ghi đè chỉ cho sự kiện này</6>.",
"unexpected_error_try_again": "Đã xảy ra lỗi không mong muốn. Hãy thử lại.", "unexpected_error_try_again": "Đã xảy ra lỗi không mong muốn. Hãy thử lại.",
"sunday_time_error": "Thời gian không hợp lệ vào Chủ Nhật", "sunday_time_error": "Thời gian không hợp lệ vào Chủ Nhật",
"monday_time_error": "Thời gian không hợp lệ vào Thứ Hai", "monday_time_error": "Thời gian không hợp lệ vào Thứ Hai",
@@ -304,6 +328,7 @@
"error_end_time_next_day": "Thời gian kết thúc không được lớn hơn 24 giờ", "error_end_time_next_day": "Thời gian kết thúc không được lớn hơn 24 giờ",
"back_to_bookings": "Quay lại các lịch hẹn", "back_to_bookings": "Quay lại các lịch hẹn",
"free_to_pick_another_event_type": "Hãy tuỳ ý chọn một sự kiện khác bất cứ lúc nào.", "free_to_pick_another_event_type": "Hãy tuỳ ý chọn một sự kiện khác bất cứ lúc nào.",
"cancelled": "Đã hủy",
"cancellation_successful": "Hủy thành công", "cancellation_successful": "Hủy thành công",
"really_cancel_booking": "Thực sự hủy lịch hẹn của bạn?", "really_cancel_booking": "Thực sự hủy lịch hẹn của bạn?",
"cannot_cancel_booking": "Bạn không thể hủy lịch hẹn này", "cannot_cancel_booking": "Bạn không thể hủy lịch hẹn này",
@@ -312,6 +337,12 @@
"cancelling_event_recurring": "Sự kiện này là một trường hợp về một sự kiện định kỳ.", "cancelling_event_recurring": "Sự kiện này là một trường hợp về một sự kiện định kỳ.",
"cancelling_all_recurring": "Đây là tất cả những trường hợp còn lại trong sự kiện định kỳ.", "cancelling_all_recurring": "Đây là tất cả những trường hợp còn lại trong sự kiện định kỳ.",
"error_with_status_code_occured": "Đã xảy ra lỗi với mã trạng thái {{status}}.", "error_with_status_code_occured": "Đã xảy ra lỗi với mã trạng thái {{status}}.",
"error_event_type_url_duplicate": "Đã tồn tại một loại sự kiện với URL này.",
"error_event_type_unauthorized_create": "Bạn không thể tạo sự kiện này",
"error_event_type_unauthorized_update": "Bạn không thể sửa sự kiện này",
"error_workflow_unauthorized_create": "Bạn không thể tạo tiến dộ công việc này",
"error_schedule_unauthorized_create": "Bạn không thể tạo lịch này",
"booking_already_cancelled": "Lịch hẹn này đã bị hủy",
"booking_already_accepted_rejected": "Lịch hẹn này đã được chấp nhận hoặc từ chối", "booking_already_accepted_rejected": "Lịch hẹn này đã được chấp nhận hoặc từ chối",
"go_back_home": "Trở về trang chủ", "go_back_home": "Trở về trang chủ",
"or_go_back_home": "Hoặc trở về trang chủ", "or_go_back_home": "Hoặc trở về trang chủ",
@@ -321,10 +352,12 @@
"no_status_bookings_yet_description": "Bạn không có lịch hẹn {{status}} nào. {{description}}", "no_status_bookings_yet_description": "Bạn không có lịch hẹn {{status}} nào. {{description}}",
"event_between_users": "{{eventName}} giữa {{host}} và {{attendeeName}}", "event_between_users": "{{eventName}} giữa {{host}} và {{attendeeName}}",
"bookings": "Các lịch hẹn", "bookings": "Các lịch hẹn",
"booking_not_found": "Lịch hẹn không tìm thấy",
"bookings_description": "Xem các sự kiện sắp tới và \btrong quá khứ mà đã đặt thông qua các liên kết loại sự kiện của bạn.", "bookings_description": "Xem các sự kiện sắp tới và \btrong quá khứ mà đã đặt thông qua các liên kết loại sự kiện của bạn.",
"upcoming_bookings": "Ngay sau khi ai đó đặt lịch với bạn, nó sẽ hiển thị ở đây.", "upcoming_bookings": "Ngay sau khi ai đó đặt lịch với bạn, nó sẽ hiển thị ở đây.",
"recurring_bookings": "Ngay sau khi ai đó đặt hẹn một cuộc họp định kỳ với bạn, nó sẽ hiển thị ở đây.", "recurring_bookings": "Ngay sau khi ai đó đặt hẹn một cuộc họp định kỳ với bạn, nó sẽ hiển thị ở đây.",
"past_bookings": "Các lịch hẹn trước đây của bạn sẽ hiển thị ở đây.", "past_bookings": "Các lịch hẹn trước đây của bạn sẽ hiển thị ở đây.",
"cancelled_bookings": "Các lịch hẹn đã hủy của bạn sẽ hiển thị ở đây.",
"unconfirmed_bookings": "Lịch hẹn chưa xác nhận của bạn sẽ hiển thị ở đây.", "unconfirmed_bookings": "Lịch hẹn chưa xác nhận của bạn sẽ hiển thị ở đây.",
"unconfirmed_bookings_tooltip": "Lịch hẹn chưa xác nhận", "unconfirmed_bookings_tooltip": "Lịch hẹn chưa xác nhận",
"on": "vào", "on": "vào",
@@ -358,15 +391,19 @@
"user_dynamic_booking_disabled": "Một số người dùng trong nhóm hiện đã tắt chức năng đặt chỗ động cho nhóm", "user_dynamic_booking_disabled": "Một số người dùng trong nhóm hiện đã tắt chức năng đặt chỗ động cho nhóm",
"allow_dynamic_booking_tooltip": "Những liên kết đặt chỗ nhóm vốn có thể được tạo linh động bằng cách thêm nhiều tên người dùng bằng một dấu '+'. Ví dụ như '{{appName}}/bailey+peer'", "allow_dynamic_booking_tooltip": "Những liên kết đặt chỗ nhóm vốn có thể được tạo linh động bằng cách thêm nhiều tên người dùng bằng một dấu '+'. Ví dụ như '{{appName}}/bailey+peer'",
"allow_dynamic_booking": "Cho phép người tham gia đặt chỗ cho bạn thông qua chức năng đặt chỗ động cho nhóm", "allow_dynamic_booking": "Cho phép người tham gia đặt chỗ cho bạn thông qua chức năng đặt chỗ động cho nhóm",
"dynamic_booking": "Liên kết động cho nhóm",
"email": "Email", "email": "Email",
"email_placeholder": "nvana@vidu.com", "email_placeholder": "nvana@vidu.com",
"full_name": "Họ và tên", "full_name": "Họ và tên",
"browse_api_documentation": "Xem qua tài liệu API của chúng tôi", "browse_api_documentation": "Xem qua tài liệu API của chúng tôi",
"leverage_our_api": "Tận dụng API của chúng tôi để có toàn quyền kiểm soát và chỉnh sửa theo ý bạn.", "leverage_our_api": "Tận dụng API của chúng tôi để có toàn quyền kiểm soát và chỉnh sửa theo ý bạn.",
"create_webhook": "Tạo Webhook", "create_webhook": "Tạo Webhook",
"booking_cancelled": "Lịch hẹn đã bị hủy",
"booking_rescheduled": "Lịch hẹn đã được đổi", "booking_rescheduled": "Lịch hẹn đã được đổi",
"recording_ready": "Đã sẵn sàng liên kết tải xuống bản ghi", "recording_ready": "Đã sẵn sàng liên kết tải xuống bản ghi",
"booking_created": "Lịch hẹn đã được tạo", "booking_created": "Lịch hẹn đã được tạo",
"booking_rejected": "Lịch hẹn đã bị từ chối",
"booking_requested": "Lịch hẹn đã được yêu cầu",
"meeting_ended": "Cuộc họp đã kết thúc", "meeting_ended": "Cuộc họp đã kết thúc",
"form_submitted": "Biểu mẫu đã được gửi", "form_submitted": "Biểu mẫu đã được gửi",
"event_triggers": "Sự kiện kích hoạt", "event_triggers": "Sự kiện kích hoạt",
@@ -376,6 +413,8 @@
"team_webhooks": "Webhooks Nhóm", "team_webhooks": "Webhooks Nhóm",
"create_new_webhook_to_account": "Tạo một webhook mới cho tài khoản của bạn", "create_new_webhook_to_account": "Tạo một webhook mới cho tài khoản của bạn",
"new_webhook": "Webhook mới", "new_webhook": "Webhook mới",
"receive_cal_meeting_data": "Nhận dữ liệu cuộc họp {{appName}} tại một URL được chỉ định, trong thời gian thực, khi một sự kiện được lên lịch hoặc hủy bỏ.",
"receive_cal_event_meeting_data": "Nhận dữ liệu cuộc họp {{appName}} tại một URL được chỉ định, trong thời gian thực, khi sự kiện này được lên lịch hoặc hủy bỏ.",
"responsive_fullscreen_iframe": "Iframe responsive toàn màn hình", "responsive_fullscreen_iframe": "Iframe responsive toàn màn hình",
"loading": "Đang tải...", "loading": "Đang tải...",
"deleting": "Đang xóa...", "deleting": "Đang xóa...",
@@ -438,6 +477,7 @@
"max_limit_allowed_hint": "Phải dài {{limit}} ký tự trở xuống", "max_limit_allowed_hint": "Phải dài {{limit}} ký tự trở xuống",
"invalid_password_hint": "Mật khẩu phải có tối thiểu {{passwordLength}} ký tự chứa ít nhất một con số và phải kết hợp chữ cái in hoa lẫn in thường", "invalid_password_hint": "Mật khẩu phải có tối thiểu {{passwordLength}} ký tự chứa ít nhất một con số và phải kết hợp chữ cái in hoa lẫn in thường",
"incorrect_password": "Mật khẩu không đúng.", "incorrect_password": "Mật khẩu không đúng.",
"incorrect_email_password": "Sai email hoặc sai mật khẩu.",
"use_setting": "Sử dụng cài đặt", "use_setting": "Sử dụng cài đặt",
"am_pm": "\u001dam/pm", "am_pm": "\u001dam/pm",
"time_options": "Tùy chọn thời gian", "time_options": "Tùy chọn thời gian",
@@ -465,6 +505,7 @@
"additional_guests": "Thêm khách", "additional_guests": "Thêm khách",
"your_name": "Tên của bạn", "your_name": "Tên của bạn",
"your_full_name": "Tên đầy đủ của bạn", "your_full_name": "Tên đầy đủ của bạn",
"no_name": "Vô danh",
"email_address": "Địa chỉ email", "email_address": "Địa chỉ email",
"enter_valid_email": "Vui lòng điền vào email hợp lệ", "enter_valid_email": "Vui lòng điền vào email hợp lệ",
"location": "Vị trí", "location": "Vị trí",
@@ -508,10 +549,13 @@
"your_team_updated_successfully": "Nhóm của bạn đã được cập nhật thành công.", "your_team_updated_successfully": "Nhóm của bạn đã được cập nhật thành công.",
"about": "Về", "about": "Về",
"team_description": "Một vài câu về nhóm của bạn. Thông tin này sẽ xuất hiện trên trang URL của nhóm của bạn.", "team_description": "Một vài câu về nhóm của bạn. Thông tin này sẽ xuất hiện trên trang URL của nhóm của bạn.",
"org_description": "Một vài câu về tổ chức của bạn. Thông tin này sẽ xuất hiện trên trang URL của tổ chức của bạn.",
"members": "Các thành viên", "members": "Các thành viên",
"organization_members": "Thành viên trong tổ chức",
"member": "Thành viên", "member": "Thành viên",
"number_member_one": "{{count}} thành viên", "number_member_one": "{{count}} thành viên",
"number_member_other": "{{count}} thành viên", "number_member_other": "{{count}} thành viên",
"number_selected": "{{count}} đã chọn",
"owner": "Chủ nhóm", "owner": "Chủ nhóm",
"admin": "Quản trị viên", "admin": "Quản trị viên",
"administrator_user": "Người dùng quản trị viên", "administrator_user": "Người dùng quản trị viên",
@@ -542,6 +586,8 @@
"confirm_all": "Xác nhận tất cả", "confirm_all": "Xác nhận tất cả",
"disband_team": "Giải tán nhóm", "disband_team": "Giải tán nhóm",
"disband_team_confirmation_message": "Bạn có chắc chắn muốn giải tán nhóm này không? Bất kỳ ai mà bạn đã chia sẻ liên kết nhóm này sẽ không thể đặt lịch hẹn với nó nữa.", "disband_team_confirmation_message": "Bạn có chắc chắn muốn giải tán nhóm này không? Bất kỳ ai mà bạn đã chia sẻ liên kết nhóm này sẽ không thể đặt lịch hẹn với nó nữa.",
"disband_org": "Giải tán tổ chức",
"disband_org_confirmation_message": "Bạn có chắc chắn muốn giải tán Tổ chức này? Tất cả các nhóm và thành viên sẽ bị xoá.",
"remove_member_confirmation_message": "Bạn có chắc chắn muốn xóa thành viên này khỏi nhóm không?", "remove_member_confirmation_message": "Bạn có chắc chắn muốn xóa thành viên này khỏi nhóm không?",
"confirm_disband_team": "Có, giải tán nhóm", "confirm_disband_team": "Có, giải tán nhóm",
"confirm_remove_member": "Có, xóa thành viên", "confirm_remove_member": "Có, xóa thành viên",
@@ -616,6 +662,7 @@
"event_type_updated_successfully": "Đã cập nhật thành công loại sự kiện {{eventTypeTitle}}", "event_type_updated_successfully": "Đã cập nhật thành công loại sự kiện {{eventTypeTitle}}",
"event_type_deleted_successfully": "Đã xóa thành công loại sự kiện", "event_type_deleted_successfully": "Đã xóa thành công loại sự kiện",
"hours": "Giờ", "hours": "Giờ",
"people": "Mọi người",
"your_email": "Email của bạn", "your_email": "Email của bạn",
"change_avatar": "Thay đổi hình đại diện", "change_avatar": "Thay đổi hình đại diện",
"language": "Ngôn ngữ", "language": "Ngôn ngữ",
@@ -648,9 +695,11 @@
"create_new_team": "Tạo một nhóm mới", "create_new_team": "Tạo một nhóm mới",
"open_invitations": "Lời mời đang chờ", "open_invitations": "Lời mời đang chờ",
"new_team": "Nhóm mới", "new_team": "Nhóm mới",
"create_first_team_and_invite_others": "Tạo nhóm đầu tiên của bạn và mời những người khác làm việc chung với bạn.",
"create_team_to_get_started": "Tạo một nhóm để bắt đầu", "create_team_to_get_started": "Tạo một nhóm để bắt đầu",
"teams": "Các nhóm", "teams": "Các nhóm",
"team": "Nhóm", "team": "Nhóm",
"organization": "Tổ chức",
"team_billing": "Thanh toán nhóm", "team_billing": "Thanh toán nhóm",
"team_billing_description": "Quản lí thanh toán cho đội ngũ của bạn", "team_billing_description": "Quản lí thanh toán cho đội ngũ của bạn",
"upgrade_to_flexible_pro_title": "Chúng tôi đã thay đổi thanh toán cho các nhóm", "upgrade_to_flexible_pro_title": "Chúng tôi đã thay đổi thanh toán cho các nhóm",
@@ -725,6 +774,7 @@
"cal_provide_huddle01_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp video Huddle01 web3.", "cal_provide_huddle01_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp video Huddle01 web3.",
"cal_provide_teams_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp MS Teams. LƯU Ý: PHẢI CÓ TÀI KHOẢN CÔNG VIỆC HOẶC TRƯỜNG HỌC", "cal_provide_teams_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp MS Teams. LƯU Ý: PHẢI CÓ TÀI KHOẢN CÔNG VIỆC HOẶC TRƯỜNG HỌC",
"require_payment": "Yêu cầu thanh toán", "require_payment": "Yêu cầu thanh toán",
"you_need_to_add_a_name": "Bạn cần thêm vào một tên",
"commission_per_transaction": "hoa hồng cho mỗi giao dịch", "commission_per_transaction": "hoa hồng cho mỗi giao dịch",
"event_type_updated_successfully_description": "Loại sự kiện của bạn đã được cập nhật thành công.", "event_type_updated_successfully_description": "Loại sự kiện của bạn đã được cập nhật thành công.",
"hide_event_type": "Ẩn loại sự kiện", "hide_event_type": "Ẩn loại sự kiện",
@@ -815,18 +865,25 @@
"installed_apps": "Ứng dụng đã cài đặt", "installed_apps": "Ứng dụng đã cài đặt",
"free_to_use_apps": "Miễn phí", "free_to_use_apps": "Miễn phí",
"no_category_apps": "Không có ứng dụng {{category}}", "no_category_apps": "Không có ứng dụng {{category}}",
"all_apps": "Tất cả các ứng dụng",
"no_category_apps_description_calendar": "Thêm một ứng dụng lịch để kiểm tra xung đột nhằm tránh đặt lịch hẹn trùng", "no_category_apps_description_calendar": "Thêm một ứng dụng lịch để kiểm tra xung đột nhằm tránh đặt lịch hẹn trùng",
"no_category_apps_description_conferencing": "Thử thêm vào một ứng dụng hội nghị dành cho các cuộc gọi video với khách hàng của bạn",
"no_category_apps_description_payment": "Thêm một ứng dụng thanh toán để đơn giản hoá giao dịch giữa bạn và khách hàng", "no_category_apps_description_payment": "Thêm một ứng dụng thanh toán để đơn giản hoá giao dịch giữa bạn và khách hàng",
"no_category_apps_description_analytics": "Thêm một ứng dụng phân tích cho những trang lịch hẹn của bạn", "no_category_apps_description_analytics": "Thêm một ứng dụng phân tích cho những trang lịch hẹn của bạn",
"no_category_apps_description_automation": "Thêm một ứng dụng tự động hoá để sử dụng", "no_category_apps_description_automation": "Thêm một ứng dụng tự động hoá để sử dụng",
"no_category_apps_description_other": "Thêm loại ứng dụng khác để làm mọi loại công việc", "no_category_apps_description_other": "Thêm loại ứng dụng khác để làm mọi loại công việc",
"no_category_apps_description_web3": "Thêm một ứng dụng web3 cho những trang lịch hẹn của bạn", "no_category_apps_description_web3": "Thêm một ứng dụng web3 cho những trang lịch hẹn của bạn",
"no_category_apps_description_messaging": "Thêm một ứng dụng nhắn tin để thiết lập thông báo & lời nhắc tuỳ chỉnh",
"no_category_apps_description_crm": "Thêm một ứng dụng CRM để theo dõi người mà bạn đã họp cùng",
"installed_app_calendar_description": "Đặt (các) lịch làm nhiệm vụ kiểm tra xung đột nhằm ngăn tình trạng đặt lịch trùng.", "installed_app_calendar_description": "Đặt (các) lịch làm nhiệm vụ kiểm tra xung đột nhằm ngăn tình trạng đặt lịch trùng.",
"installed_app_payment_description": "Cấu hình loại dịch vụ xử lí thanh toán nào sẽ được dùng đến khi thu phí khách hàng.", "installed_app_payment_description": "Cấu hình loại dịch vụ xử lí thanh toán nào sẽ được dùng đến khi thu phí khách hàng.",
"installed_app_analytics_description": "Cấu hình ứng dụng phân tích nào để sử dụng cho những trang lịch hẹn của bạn", "installed_app_analytics_description": "Cấu hình ứng dụng phân tích nào để sử dụng cho những trang lịch hẹn của bạn",
"installed_app_other_description": "Tất cả những ứng dụng bạn đã cài từ những danh mục khác.", "installed_app_other_description": "Tất cả những ứng dụng bạn đã cài từ những danh mục khác.",
"installed_app_conferencing_description": "Cấu hình ứng dụng hội nghị nào nên dùng",
"installed_app_automation_description": "Cấu hình ứng dụng tự động hoá nên dùng", "installed_app_automation_description": "Cấu hình ứng dụng tự động hoá nên dùng",
"installed_app_web3_description": "Cấu hình ứng dụng web3 nào cần để sử dụng cho những trang lịch hẹn của bạn", "installed_app_web3_description": "Cấu hình ứng dụng web3 nào cần để sử dụng cho những trang lịch hẹn của bạn",
"installed_app_messaging_description": "Cấu hình ứng dụng nhắn tin nào cần dùng để thiết lập thông báo & lời nhắc tuỳ chỉnh",
"installed_app_crm_description": "Cấu hình ứng dụng CRM nào cần dùng để theo dõi những người mà bạn đã họp cùng",
"analytics": "Phân tích", "analytics": "Phân tích",
"empty_installed_apps_headline": "Chưa cài ứng dụng nào", "empty_installed_apps_headline": "Chưa cài ứng dụng nào",
"empty_installed_apps_description": "Ứng dụng cho phép bạn cải thiện tiến độ công việc và cải thiện đáng kể việc sắp xếp tổ chức.", "empty_installed_apps_description": "Ứng dụng cho phép bạn cải thiện tiến độ công việc và cải thiện đáng kể việc sắp xếp tổ chức.",
@@ -852,6 +909,7 @@
"create_events_on": "Tạo sự kiện trên", "create_events_on": "Tạo sự kiện trên",
"enterprise_license": "Đây là tính năng doanh nghiệp", "enterprise_license": "Đây là tính năng doanh nghiệp",
"enterprise_license_description": "Để bật tính năng này, nhận khoá triển khai tại console {{consoleUrl}} và thêm nó vào .env của bạn ở dạng CALCOM_LICENSE_KEY. Nếu nhóm của bạn đã có giấy phép, vui lòng liên hệ {{supportMail}} để được trợ giúp.", "enterprise_license_description": "Để bật tính năng này, nhận khoá triển khai tại console {{consoleUrl}} và thêm nó vào .env của bạn ở dạng CALCOM_LICENSE_KEY. Nếu nhóm của bạn đã có giấy phép, vui lòng liên hệ {{supportMail}} để được trợ giúp.",
"enterprise_license_development": "Bạn có thể kiểm tra tính năng này ở thể thức phát triển. Để sử dụng ở dạng sản xuất, hãy nhờ quản trị viên vào phần <2>/auth/setup</2> để nhập một khoá giấy phép.",
"missing_license": "Giấy phép bị thiếu", "missing_license": "Giấy phép bị thiếu",
"signup_requires": "Yêu cầu giấy phép thương mại", "signup_requires": "Yêu cầu giấy phép thương mại",
"signup_requires_description": "{{companyName}} hiện không cung cấp phiên bản nguồn mở miễn phí của trang đăng ký. Để nhận toàn quyền truy cập vào các thành phần đăng ký, bạn cần có giấy phép thương mại. Đối với mục đích sử dụng cá nhân, chúng tôi khuyên bạn nên sử dụng Nền tảng dữ liệu Prisma hoặc bất kỳ giao diện Postgres nào khác để tạo tài khoản.", "signup_requires_description": "{{companyName}} hiện không cung cấp phiên bản nguồn mở miễn phí của trang đăng ký. Để nhận toàn quyền truy cập vào các thành phần đăng ký, bạn cần có giấy phép thương mại. Đối với mục đích sử dụng cá nhân, chúng tôi khuyên bạn nên sử dụng Nền tảng dữ liệu Prisma hoặc bất kỳ giao diện Postgres nào khác để tạo tài khoản.",
@@ -921,6 +979,7 @@
"confirm_delete_api_key": "Thu hồi khóa API này", "confirm_delete_api_key": "Thu hồi khóa API này",
"revoke_api_key": "Thu hồi khóa API", "revoke_api_key": "Thu hồi khóa API",
"api_key_copied": "Khoá API đã sao chép!", "api_key_copied": "Khoá API đã sao chép!",
"api_key_expires_on": "Khoá API sẽ hết hạn vào",
"delete_api_key_confirm_title": "Xoá bỏ vĩnh viễn khóa API này ra khỏi tài khoản của bạn?", "delete_api_key_confirm_title": "Xoá bỏ vĩnh viễn khóa API này ra khỏi tài khoản của bạn?",
"copy": "Sao chép", "copy": "Sao chép",
"expire_date": "Ngày hết hiệu lực", "expire_date": "Ngày hết hiệu lực",
@@ -943,6 +1002,9 @@
"user_impersonation_heading": "Mạo danh người dùng", "user_impersonation_heading": "Mạo danh người dùng",
"user_impersonation_description": "Cho phép đội ngũ hỗ trợ tạm thời đăng nhập với tư cách là bạn nhằm giúp chúng tôi nhanh chóng giải quyết mọi vấn đề mà bạn báo cáo cho chúng tôi.", "user_impersonation_description": "Cho phép đội ngũ hỗ trợ tạm thời đăng nhập với tư cách là bạn nhằm giúp chúng tôi nhanh chóng giải quyết mọi vấn đề mà bạn báo cáo cho chúng tôi.",
"team_impersonation_description": "Cho phép các quản trị viên của nhóm bạn tạm thời đăng nhập bằng danh tính của bạn.", "team_impersonation_description": "Cho phép các quản trị viên của nhóm bạn tạm thời đăng nhập bằng danh tính của bạn.",
"make_team_private": "Để nhóm ở mức riêng tư",
"make_team_private_description": "Thành viên nhóm của bạn sẽ không thể thấy thành viên nhóm khác khi cái này được bật.",
"you_cannot_see_team_members": "Bạn không thể thấy tất cả thành viên nhóm của một nhóm riêng tư.",
"allow_booker_to_select_duration": "Cho phép người đặt hẹn chọn khoảng thời gian", "allow_booker_to_select_duration": "Cho phép người đặt hẹn chọn khoảng thời gian",
"impersonate_user_tip": "Tất cả những lần dùng tính năng này đều bị kiểm toán.", "impersonate_user_tip": "Tất cả những lần dùng tính năng này đều bị kiểm toán.",
"impersonating_user_warning": "Đang mạo danh tên người dùng \"{{user}}\".", "impersonating_user_warning": "Đang mạo danh tên người dùng \"{{user}}\".",
@@ -1010,16 +1072,21 @@
"event_location": "Địa điểm sự kiện", "event_location": "Địa điểm sự kiện",
"reschedule_optional": "Lí do xếp lịch lại (tuỳ chọn)", "reschedule_optional": "Lí do xếp lịch lại (tuỳ chọn)",
"reschedule_placeholder": "Cho người khác biết nguyên do bạn cần xếp lịch lại", "reschedule_placeholder": "Cho người khác biết nguyên do bạn cần xếp lịch lại",
"event_cancelled": "Sự kiệnn này bị huỷ",
"emailed_information_about_cancelled_event": "Chúng tôi đã gửi email cho bạn và những người tham dự khác để cho họ biết.", "emailed_information_about_cancelled_event": "Chúng tôi đã gửi email cho bạn và những người tham dự khác để cho họ biết.",
"this_input_will_shown_booking_this_event": "Trường này sẽ được hiển thị khi đặt sự kiện này", "this_input_will_shown_booking_this_event": "Trường này sẽ được hiển thị khi đặt sự kiện này",
"meeting_url_in_conformation_email": "Url cuộc họp nằm trong email xác nhận", "meeting_url_in_conformation_email": "Url cuộc họp nằm trong email xác nhận",
"url_start_with_https": "URL cần bắt đầu bằng http:// hoặc https://", "url_start_with_https": "URL cần bắt đầu bằng http:// hoặc https://",
"number_provided": "Số điện thoại sẽ được cung ứng", "number_provided": "Số điện thoại sẽ được cung ứng",
"before_event_trigger": "trước khi sự kiện bắt đầu", "before_event_trigger": "trước khi sự kiện bắt đầu",
"event_cancelled_trigger": "khi sự kiện bị huỷ",
"new_event_trigger": "khi sự kiện mới được đặt lịch hẹn", "new_event_trigger": "khi sự kiện mới được đặt lịch hẹn",
"email_host_action": "gửi email đến chủ sự kiện", "email_host_action": "gửi email đến chủ sự kiện",
"email_attendee_action": "gửi email đến người tham gia", "email_attendee_action": "gửi email đến người tham gia",
"sms_attendee_action": "Gửi SMS đến người tham gia",
"sms_number_action": "gửi SMS đến một số cụ thể", "sms_number_action": "gửi SMS đến một số cụ thể",
"whatsapp_number_action": "gửi WhatsApp đến một số cụ thể",
"whatsapp_attendee_action": "gửi WhatsApp đến người tham gia",
"workflows": "Tiến độ công việc", "workflows": "Tiến độ công việc",
"new_workflow_btn": "Dòng công việc mới", "new_workflow_btn": "Dòng công việc mới",
"add_new_workflow": "Thêm một tiến độ công việc mới", "add_new_workflow": "Thêm một tiến độ công việc mới",
@@ -1083,6 +1150,8 @@
"choose_template": "Chọn mẫu", "choose_template": "Chọn mẫu",
"custom": "Tuỳ chỉnh", "custom": "Tuỳ chỉnh",
"reminder": "Lời nhắc", "reminder": "Lời nhắc",
"rescheduled": "Thay đổi lịch hẹn",
"completed": "Đã hoàn thành",
"reminder_email": "Lời nhắc: {{eventType}} với {{name}} vào {{date}}", "reminder_email": "Lời nhắc: {{eventType}} với {{name}} vào {{date}}",
"not_triggering_existing_bookings": "Sẽ không kích hoạt đối với những lịch hẹn đã có do người dùng sẽ được yêu cầu số điện thoại khi đặt lịch hẹn cho sự kiện.", "not_triggering_existing_bookings": "Sẽ không kích hoạt đối với những lịch hẹn đã có do người dùng sẽ được yêu cầu số điện thoại khi đặt lịch hẹn cho sự kiện.",
"minute_one": "{{count}} phút", "minute_one": "{{count}} phút",
@@ -1180,6 +1249,7 @@
"start_of_week": "Khởi đầu tuần", "start_of_week": "Khởi đầu tuần",
"recordings_title": "Bản ghi âm", "recordings_title": "Bản ghi âm",
"recording": "Bản ghi âm", "recording": "Bản ghi âm",
"happy_scheduling": "Chúc bạn đặt lịch vui vẻ",
"select_calendars": "Chọn lịch nào mà bạn muốn kiểm tra xung đột nhằm tránh đặt lịch hẹn trùng.", "select_calendars": "Chọn lịch nào mà bạn muốn kiểm tra xung đột nhằm tránh đặt lịch hẹn trùng.",
"check_for_conflicts": "Kiểm tra xung đột", "check_for_conflicts": "Kiểm tra xung đột",
"view_recordings": "Xem các bản ghi âm", "view_recordings": "Xem các bản ghi âm",
@@ -1221,6 +1291,7 @@
"conferencing_description": "Quản lí ứng dụng hội nghị video dùng cho các cuộc họp", "conferencing_description": "Quản lí ứng dụng hội nghị video dùng cho các cuộc họp",
"add_conferencing_app": "Thêm ứng dụng hội nghị", "add_conferencing_app": "Thêm ứng dụng hội nghị",
"password_description": "Quản lí cài đặt cho mật khẩu tài khoản", "password_description": "Quản lí cài đặt cho mật khẩu tài khoản",
"set_up_two_factor_authentication": "Thiết lập xác thực hai yếu tố",
"we_just_need_basic_info": "Chúng tôi chỉ cần một số thông tin cơ bản để thiết lập hồ sơ của bạn.", "we_just_need_basic_info": "Chúng tôi chỉ cần một số thông tin cơ bản để thiết lập hồ sơ của bạn.",
"skip": "Bỏ qua", "skip": "Bỏ qua",
"do_this_later": "Làm việc này sau", "do_this_later": "Làm việc này sau",
@@ -1234,6 +1305,8 @@
"connect_analytics_apps": "Kết nối các ứng dụng phân tích", "connect_analytics_apps": "Kết nối các ứng dụng phân tích",
"connect_other_apps": "Kết nối các ứng dụng khác", "connect_other_apps": "Kết nối các ứng dụng khác",
"connect_web3_apps": "Kết nối các ứng dụng web3", "connect_web3_apps": "Kết nối các ứng dụng web3",
"connect_messaging_apps": "Kết nối các ứng dụng nhắn tin",
"connect_crm_apps": "Kết nối các ứng dụng CRM",
"current_step_of_total": "Bước {{currentStep}}/{{maxSteps}}", "current_step_of_total": "Bước {{currentStep}}/{{maxSteps}}",
"add_variable": "Thêm biến số", "add_variable": "Thêm biến số",
"custom_phone_number": "Số điện thoại tùy chỉnh", "custom_phone_number": "Số điện thoại tùy chỉnh",
@@ -1246,12 +1319,14 @@
"location_info": "Địa điểm sự kiện", "location_info": "Địa điểm sự kiện",
"additional_notes_info": "Ghi chú thêm cho lịch hẹn", "additional_notes_info": "Ghi chú thêm cho lịch hẹn",
"attendee_name_info": "Tên người tham gia lịch hẹn", "attendee_name_info": "Tên người tham gia lịch hẹn",
"organizer_name_info": "Tên của tổ chức",
"to": "Đến", "to": "Đến",
"workflow_turned_on_successfully": "Đã {{offOn}} thành công dòng công việc {{workflowName}}", "workflow_turned_on_successfully": "Đã {{offOn}} thành công dòng công việc {{workflowName}}",
"download_responses": "Tải xuống phản hồi", "download_responses": "Tải xuống phản hồi",
"download_responses_description": "Tải xuống tất cả phản hồi vào biểu mẫu của bạn ở định dạng CSV.", "download_responses_description": "Tải xuống tất cả phản hồi vào biểu mẫu của bạn ở định dạng CSV.",
"download": "Tải về", "download": "Tải về",
"download_recording": "Tải xuống bản ghi âm", "download_recording": "Tải xuống bản ghi âm",
"recording_from_your_recent_call": "Một bản ghi âm từ cuộc gọi gần đây trên {{appName}} đã sẵn sàng để tải xuống",
"create_your_first_form": "Tạo biểu mẫu đầu tiên", "create_your_first_form": "Tạo biểu mẫu đầu tiên",
"create_your_first_form_description": "Với Biểu mẫu định hướng, bạn có thể hỏi một số câu sơ tuyển và định hướng đến đúng người hay đúng loại sự kiện.", "create_your_first_form_description": "Với Biểu mẫu định hướng, bạn có thể hỏi một số câu sơ tuyển và định hướng đến đúng người hay đúng loại sự kiện.",
"create_your_first_webhook": "Tạo Webhook đầu tiên", "create_your_first_webhook": "Tạo Webhook đầu tiên",
@@ -1260,7 +1335,9 @@
"event_one": "sự kiện", "event_one": "sự kiện",
"event_other": "sự kiện", "event_other": "sự kiện",
"profile_team_description": "Quản lí cài đặt cho hồ sơ nhóm của bạn", "profile_team_description": "Quản lí cài đặt cho hồ sơ nhóm của bạn",
"profile_org_description": "Quản lí cài đặt cho hồ sơ tổ chức của bạn",
"members_team_description": "Những người dùng đang ở trong nhóm", "members_team_description": "Những người dùng đang ở trong nhóm",
"organization_description": "Quản lí những quản trị viên và thành viên trong tổ chức của bạn",
"team_url": "URL nhóm", "team_url": "URL nhóm",
"team_members": "Thành viên nhóm", "team_members": "Thành viên nhóm",
"more": "Khác", "more": "Khác",
@@ -1301,6 +1378,7 @@
"routing_forms_send_email_owner": "Gửi email đến chủ sở hữu", "routing_forms_send_email_owner": "Gửi email đến chủ sở hữu",
"routing_forms_send_email_owner_description": "Gửi một email đến chủ sở hữu khi biểu mẫu được gửi đi", "routing_forms_send_email_owner_description": "Gửi một email đến chủ sở hữu khi biểu mẫu được gửi đi",
"add_new_form": "Thêm biểu mẫu mới", "add_new_form": "Thêm biểu mẫu mới",
"add_new_team_form": "Thêm biểu mẫu mới vào nhóm bạn",
"create_your_first_route": "Tạo định hướng đầu tiên của bạn", "create_your_first_route": "Tạo định hướng đầu tiên của bạn",
"route_to_the_right_person": "Định hướng đến người phù hợp dựa trên những câu trả lời cho biểu mẫu của bạn", "route_to_the_right_person": "Định hướng đến người phù hợp dựa trên những câu trả lời cho biểu mẫu của bạn",
"form_description": "Tạo biểu mẫu của bạn để định hướng người đặt lịch hẹn", "form_description": "Tạo biểu mẫu của bạn để định hướng người đặt lịch hẹn",
@@ -1386,6 +1464,7 @@
"new_event_type_availability": "Tình trạng trống lịch của {{eventTypeTitle}}", "new_event_type_availability": "Tình trạng trống lịch của {{eventTypeTitle}}",
"error_editing_availability": "Lỗi sửa tình trạng trống lịch", "error_editing_availability": "Lỗi sửa tình trạng trống lịch",
"dont_have_permission": "Bạn không có quyền truy cập tài nguyên này.", "dont_have_permission": "Bạn không có quyền truy cập tài nguyên này.",
"saml_config": "SAML",
"saml_configuration_placeholder": "Vui lòng dán metadata SAML từ Nhà cung cấp danh tính của bạn tại đây", "saml_configuration_placeholder": "Vui lòng dán metadata SAML từ Nhà cung cấp danh tính của bạn tại đây",
"saml_email_required": "Vui lòng nhập email để chúng tôi có thể tìm thấy Nhà cung cấp danh tính SAML của bạn", "saml_email_required": "Vui lòng nhập email để chúng tôi có thể tìm thấy Nhà cung cấp danh tính SAML của bạn",
"saml_sp_title": "Chi tiết nhà cung cấp dịch vụ", "saml_sp_title": "Chi tiết nhà cung cấp dịch vụ",
@@ -1404,15 +1483,19 @@
"yearly": "Hằng năm", "yearly": "Hằng năm",
"checkout": "Thanh toán", "checkout": "Thanh toán",
"your_team_disbanded_successfully": "Nhóm của bạn đã được giải tán thành công", "your_team_disbanded_successfully": "Nhóm của bạn đã được giải tán thành công",
"your_org_disbanded_successfully": "Tổ chức của bạn đã được giải tán thành công",
"error_creating_team": "Lỗi khi tạo nhóm", "error_creating_team": "Lỗi khi tạo nhóm",
"you": "Bạn", "you": "Bạn",
"resend_email": "Gửi lại email",
"member_already_invited": "Thành viên đã được mời rồi", "member_already_invited": "Thành viên đã được mời rồi",
"enter_email_or_username": "Nhập một email hoặc tên người dùng", "enter_email_or_username": "Nhập một email hoặc tên người dùng",
"team_name_taken": "Tên này đã có người lấy rồi", "team_name_taken": "Tên này đã có người lấy rồi",
"must_enter_team_name": "Cần phải nhập một tên nhóm", "must_enter_team_name": "Cần phải nhập một tên nhóm",
"team_url_required": "Cần phải nhập một URL của nhóm", "team_url_required": "Cần phải nhập một URL của nhóm",
"url_taken": "URL này đã có người lấy rồi", "url_taken": "URL này đã có người lấy rồi",
"problem_registering_domain": "Có vấn đề với việc đăng ký tên miền phụ, vui lòng thử lại hoặc liên lạc với quản trị viên",
"team_publish": "Đăng nhóm", "team_publish": "Đăng nhóm",
"number_text_notifications": "Số điện thoại (thông báo tin nhắn van bản)",
"attendee_email_variable": "Email người tham dự", "attendee_email_variable": "Email người tham dự",
"attendee_email_info": "Email người tham gia lịch hẹn", "attendee_email_info": "Email người tham gia lịch hẹn",
"kbar_search_placeholder": "Nhập một lệnh hoặc tìm kiếm...", "kbar_search_placeholder": "Nhập một lệnh hoặc tìm kiếm...",
@@ -1435,6 +1518,8 @@
"find_the_best_person": "Tìm người tốt nhất có được và xoay vòng trong nhóm bạn.", "find_the_best_person": "Tìm người tốt nhất có được và xoay vòng trong nhóm bạn.",
"fixed_round_robin": "Round robin cố định", "fixed_round_robin": "Round robin cố định",
"add_one_fixed_attendee": "Thêm một người tham dự và round robin cố định thông qua số người tham dự.", "add_one_fixed_attendee": "Thêm một người tham dự và round robin cố định thông qua số người tham dự.",
"calcom_is_better_with_team": "{{appName}} tốt hơn với nhóm",
"the_calcom_team": "Nhóm của {{companyName}}",
"add_your_team_members": "Thêm những thành viên nhóm của bạn vào những loại sự kiện của bạn. Sử dụng lên lịch tập thể để bao gồm mọi người hoặc tìm người thích hợp nhất với chức năng lên lịch round robin.", "add_your_team_members": "Thêm những thành viên nhóm của bạn vào những loại sự kiện của bạn. Sử dụng lên lịch tập thể để bao gồm mọi người hoặc tìm người thích hợp nhất với chức năng lên lịch round robin.",
"booking_limit_reached": "Đã đạt mức giới hạn đặt hẹn cho loại sự kiện này", "booking_limit_reached": "Đã đạt mức giới hạn đặt hẹn cho loại sự kiện này",
"duration_limit_reached": "Đã đạt mức giới hạn thời gian cho loại sự kiện này", "duration_limit_reached": "Đã đạt mức giới hạn thời gian cho loại sự kiện này",
@@ -1453,6 +1538,7 @@
"navigate_installed_apps": "Đến những ứng dụng được cài đặt", "navigate_installed_apps": "Đến những ứng dụng được cài đặt",
"disabled_calendar": "Nếu bạn có lịch khác được cài đặt, những mục đặt hẹn mới sẽ được thêm vào đó. Nếu không thì hãy kết nối với lịch mới để bạn không bỏ lỡ bất cứ mục đặt hẹn mới nào.", "disabled_calendar": "Nếu bạn có lịch khác được cài đặt, những mục đặt hẹn mới sẽ được thêm vào đó. Nếu không thì hãy kết nối với lịch mới để bạn không bỏ lỡ bất cứ mục đặt hẹn mới nào.",
"enable_apps": "Kích hoạt ứng dụng", "enable_apps": "Kích hoạt ứng dụng",
"enable_apps_description": "Kích hoạt những ứng dụng mà người dùng có thể tích hợp với {{appName}}",
"purchase_license": "Mua một giấy phép", "purchase_license": "Mua một giấy phép",
"already_have_key": "Tôi đã có một khoá:", "already_have_key": "Tôi đã có một khoá:",
"already_have_key_suggestion": "Vui lòng sao chép biến số môi trường CALCOM_LICENSE_KEY hiện có của bạn tại đây.", "already_have_key_suggestion": "Vui lòng sao chép biến số môi trường CALCOM_LICENSE_KEY hiện có của bạn tại đây.",
@@ -1466,6 +1552,9 @@
"no_available_apps": "Không có ứng dụng nào khả dụng", "no_available_apps": "Không có ứng dụng nào khả dụng",
"no_available_apps_description": "Vui lòng bảo đảm rằng có những ứng dụng trong phần triển khai trong 'packages/app-store'", "no_available_apps_description": "Vui lòng bảo đảm rằng có những ứng dụng trong phần triển khai trong 'packages/app-store'",
"no_apps": "Không ứng dụng được kích hoạt cho thể hiện này của Cal", "no_apps": "Không ứng dụng được kích hoạt cho thể hiện này của Cal",
"no_apps_configured": "Chưa cấu hình ứng dụng nào",
"enable_in_settings": "Bạn có thể bật các ứng dụng trong cài đặt",
"please_contact_admin": "Vui lòng liên lạc với quản trị viên",
"apps_settings": "Cài đặt của ứng dụng", "apps_settings": "Cài đặt của ứng dụng",
"fill_this_field": "Vui lòng điền vào trường này", "fill_this_field": "Vui lòng điền vào trường này",
"options": "Tuỳ chọn", "options": "Tuỳ chọn",
@@ -1571,6 +1660,8 @@
"email_user_cta": "Xem lời mời", "email_user_cta": "Xem lời mời",
"email_no_user_invite_heading": "Bạn đã được mời gia nhập {{entity}} {{appName}}", "email_no_user_invite_heading": "Bạn đã được mời gia nhập {{entity}} {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập nhóm của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và nhóm bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.", "email_no_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập nhóm của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và nhóm bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.",
"email_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập {{entity}} '{{teamName}}' của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và {{entity}} của bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.",
"email_no_user_invite_steps_intro": "Chúng tôi sẽ hướng dẫn cho bạn qua vài bước nhỏ và bạn sẽ tận hưởng được ngay cảm giác thoải mái không căng thẳng trong việc lên lịch cùng {{entity}} của mình.",
"email_no_user_step_one": "Chọn tên người dùng của bạn", "email_no_user_step_one": "Chọn tên người dùng của bạn",
"email_no_user_step_two": "Kết nối tài khoản lịch của bạn", "email_no_user_step_two": "Kết nối tài khoản lịch của bạn",
"email_no_user_step_three": "Đặt lịch khả dụng của bạn", "email_no_user_step_three": "Đặt lịch khả dụng của bạn",
@@ -1581,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "Không có dòng công việc", "no_workflows": "Không có dòng công việc",
"change_filter": "Đổi bộ lọc để xem dòng công việc của cá nhân và của nhóm.", "change_filter": "Đổi bộ lọc để xem dòng công việc của cá nhân và của nhóm.",
"change_filter_common": "Thay đổi bộ lọc để xem kết quả.",
"no_results_for_filter": "Không có kết quả nào dành cho bộ lọc",
"recommended_next_steps": "Những bước tiếp theo được đề xuất", "recommended_next_steps": "Những bước tiếp theo được đề xuất",
"create_a_managed_event": "Tạo một loại sự kiện được quản lý", "create_a_managed_event": "Tạo một loại sự kiện được quản lý",
"meetings_are_better_with_the_right": "Các cuộc họp sẽ ổn hơn khi có những thành viên nhóm phù hợp ở đó. Hãy mời họ ngay.", "meetings_are_better_with_the_right": "Các cuộc họp sẽ ổn hơn khi có những thành viên nhóm phù hợp ở đó. Hãy mời họ ngay.",
@@ -1591,6 +1684,7 @@
"no_longer_attending": "Bạn không còn tham gia sự kiện này nữa", "no_longer_attending": "Bạn không còn tham gia sự kiện này nữa",
"attendee_no_longer_attending_subject": "Một người tham dự không còn tham dự {{title}} vào {{date}}", "attendee_no_longer_attending_subject": "Một người tham dự không còn tham dự {{title}} vào {{date}}",
"attendee_no_longer_attending": "Một người tham dự không còn tham dự sự kiện của bạn", "attendee_no_longer_attending": "Một người tham dự không còn tham dự sự kiện của bạn",
"attendee_no_longer_attending_subtitle": "{{name}} đã hủy. Điều này nghĩa là còn lại một suất cho thời điểm này",
"create_event_on": "Tạo sự kiện vào", "create_event_on": "Tạo sự kiện vào",
"create_routing_form_on": "Tạo biểu mẫu định hướng trên", "create_routing_form_on": "Tạo biểu mẫu định hướng trên",
"default_app_link_title": "Đặt một liên kết ứng dụng mặc định", "default_app_link_title": "Đặt một liên kết ứng dụng mặc định",
@@ -1602,6 +1696,7 @@
"booking_questions_title": "Các câu hỏi lịch hẹn", "booking_questions_title": "Các câu hỏi lịch hẹn",
"booking_questions_description": "Tùy chỉnh các câu hỏi ở trang đặt lịch hẹn", "booking_questions_description": "Tùy chỉnh các câu hỏi ở trang đặt lịch hẹn",
"add_a_booking_question": "Thêm một câu hỏi", "add_a_booking_question": "Thêm một câu hỏi",
"identifier": "Mã định danh",
"duplicate_email": "Email bị trùng", "duplicate_email": "Email bị trùng",
"booking_with_payment_cancelled": "Việc thanh toán cho sự kiện này không còn khả thi nữa", "booking_with_payment_cancelled": "Việc thanh toán cho sự kiện này không còn khả thi nữa",
"booking_with_payment_cancelled_already_paid": "Đang thực hiện một khoản hoàn tiền cho phần thanh toán lịch hẹn này.", "booking_with_payment_cancelled_already_paid": "Đang thực hiện một khoản hoàn tiền cho phần thanh toán lịch hẹn này.",
@@ -1612,6 +1707,7 @@
"show_on_booking_page": "Hiện trên trang lịch hẹn", "show_on_booking_page": "Hiện trên trang lịch hẹn",
"get_started_zapier_templates": "Bắt đầu với các mẫu Zapier", "get_started_zapier_templates": "Bắt đầu với các mẫu Zapier",
"team_is_unpublished": "{{team}} chưa được công bố", "team_is_unpublished": "{{team}} chưa được công bố",
"team_is_unpublished_description": "Liên kết {{entity}} này hiện không khả dụng. Hãy liên lạc với chủ {{entity}} hoặc yêu cầu họ công bố liên kết đó.",
"team_member": "Thành viên nhóm", "team_member": "Thành viên nhóm",
"a_routing_form": "Một biểu mẫu định hướng", "a_routing_form": "Một biểu mẫu định hướng",
"form_description_placeholder": "Mô tả biểu mẫu", "form_description_placeholder": "Mô tả biểu mẫu",
@@ -1641,13 +1737,16 @@
"spot_popular_event_types": "Nhận ra các loại sự kiện phổ biến", "spot_popular_event_types": "Nhận ra các loại sự kiện phổ biến",
"spot_popular_event_types_description": "Xem loại sự kiện nào của bạn nhận được nhiều lần nhấp chuột và nhiều lịch hẹn nhất", "spot_popular_event_types_description": "Xem loại sự kiện nào của bạn nhận được nhiều lần nhấp chuột và nhiều lịch hẹn nhất",
"no_responses_yet": "Chưa có hồi đáp", "no_responses_yet": "Chưa có hồi đáp",
"no_routes_defined": "Không xác định được định hướng",
"this_will_be_the_placeholder": "Đây sẽ là mã giữ chỗ", "this_will_be_the_placeholder": "Đây sẽ là mã giữ chỗ",
"error_booking_event": "Có lỗi khi đặt lịch sự kiện, hãy làm mới trang rồi thử lại",
"timeslot_missing_title": "Chưa chọn suất thời gian nào", "timeslot_missing_title": "Chưa chọn suất thời gian nào",
"timeslot_missing_description": "Vui lòng chọn một suất thời gian để đặt lịch sự kiện.", "timeslot_missing_description": "Vui lòng chọn một suất thời gian để đặt lịch sự kiện.",
"timeslot_missing_cta": "Chọn suất thời gian", "timeslot_missing_cta": "Chọn suất thời gian",
"switch_monthly": "Chuyển sang giao diện tháng", "switch_monthly": "Chuyển sang giao diện tháng",
"switch_weekly": "Chuyển sang giao diện tuần", "switch_weekly": "Chuyển sang giao diện tuần",
"switch_multiday": "Chuyển sang giao diện ngày", "switch_multiday": "Chuyển sang giao diện ngày",
"switch_columnview": "Chuyển sang giao diện cột",
"num_locations": "{{num}} lựa chọn vị trí", "num_locations": "{{num}} lựa chọn vị trí",
"select_on_next_step": "Chọn ở bước kế tiếp", "select_on_next_step": "Chọn ở bước kế tiếp",
"this_meeting_has_not_started_yet": "Cuộc hẹn này chưa được bắt đầu", "this_meeting_has_not_started_yet": "Cuộc hẹn này chưa được bắt đầu",
@@ -1686,6 +1785,7 @@
"managed_event_dialog_title_one": "URL / {{slug}} đã có sẵn cho {{count}} thành viên. Bạn có muốn thay thế nó?", "managed_event_dialog_title_one": "URL / {{slug}} đã có sẵn cho {{count}} thành viên. Bạn có muốn thay thế nó?",
"managed_event_dialog_title_other": "URL /{{slug}} đã có sẵn cho {{count}} thành viên. Bạn có muốn thay thế nó?", "managed_event_dialog_title_other": "URL /{{slug}} đã có sẵn cho {{count}} thành viên. Bạn có muốn thay thế nó?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> đã dùng URL <strong>/{{slug}}</strong> rồi.", "managed_event_dialog_information_one": "<strong>{{names}}</strong> đã dùng URL <strong>/{{slug}}</strong> rồi.",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> đã dùng URL <strong>/{{slug}}</strong> rồi.",
"managed_event_dialog_clarification": "Nếu bạn chọn phương án thay thế nó, chúng tôi sẽ thông báo cho họ biết. Hãy quay lại và xóa bỏ họ nếu bạn không muốn ghi đè nó.", "managed_event_dialog_clarification": "Nếu bạn chọn phương án thay thế nó, chúng tôi sẽ thông báo cho họ biết. Hãy quay lại và xóa bỏ họ nếu bạn không muốn ghi đè nó.",
"review_event_type": "Xem lại loại sự kiện", "review_event_type": "Xem lại loại sự kiện",
"looking_for_more_analytics": "Bạn muốn có thêm thông tin phân tích?", "looking_for_more_analytics": "Bạn muốn có thêm thông tin phân tích?",
@@ -1701,12 +1801,14 @@
"least_booked_members": "Thành viên được đặt lịch hẹn ít nhất", "least_booked_members": "Thành viên được đặt lịch hẹn ít nhất",
"events_created": "Những sự kiện đã tạo", "events_created": "Những sự kiện đã tạo",
"events_completed": "Những sự kiện đã hoàn thành", "events_completed": "Những sự kiện đã hoàn thành",
"events_cancelled": "Những sự kiện đã hủy",
"events_rescheduled": "Những sự kiện đã đặt lịch lại", "events_rescheduled": "Những sự kiện đã đặt lịch lại",
"from_last_period": "từ thời gian gần nhất", "from_last_period": "từ thời gian gần nhất",
"from_to_date_period": "Từ: {{startDate}} Đến: {{endDate}}", "from_to_date_period": "Từ: {{startDate}} Đến: {{endDate}}",
"redirect_url_warning": "Thêm mục chuyển hướng sẽ tắt đi trang thành công. Hãy bảo đảm có đề cập \"Lịch hẹn đã xác nhận\" trên trang thành công tuỳ chỉnh riêng của bạn.", "redirect_url_warning": "Thêm mục chuyển hướng sẽ tắt đi trang thành công. Hãy bảo đảm có đề cập \"Lịch hẹn đã xác nhận\" trên trang thành công tuỳ chỉnh riêng của bạn.",
"event_trends": "Xu hướng sự kiện", "event_trends": "Xu hướng sự kiện",
"clear_filters": "Xóa bộ lọc", "clear_filters": "Xóa bộ lọc",
"clear": "Xoá",
"hold": "Tạm giữ", "hold": "Tạm giữ",
"on_booking_option": "Thu tiền thanh toán cho lịch hẹn", "on_booking_option": "Thu tiền thanh toán cho lịch hẹn",
"hold_option": "Tính phí vắng mặt", "hold_option": "Tính phí vắng mặt",
@@ -1733,6 +1835,18 @@
"complete_your_booking": "Hoàn thành lịch hẹn của bạn", "complete_your_booking": "Hoàn thành lịch hẹn của bạn",
"complete_your_booking_subject": "Hoàn thành lịch hẹn của bạn: {{title}} vào {{date}}", "complete_your_booking_subject": "Hoàn thành lịch hẹn của bạn: {{title}} vào {{date}}",
"confirm_your_details": "Xác nhận các chi tiết của bạn", "confirm_your_details": "Xác nhận các chi tiết của bạn",
"copy_invite_link": "Sao chép liên kết mời",
"edit_invite_link": "Sửa cài đặt liên kết",
"invite_link_copied": "Liên kết lời mời đã được sao chép",
"invite_link_deleted": "Liên kết lời mời đã được xoá",
"invite_link_updated": "Đã lưu cài đặt cho liên kết lời mời",
"link_expires_after": "Các liên kết được đặt hết hạn sau...",
"one_day": "1 ngày",
"seven_days": "7 ngày",
"thirty_days": "30 ngày",
"three_months": "3 tháng",
"one_year": "1 năm",
"team_invite_received": "Bạn đã được mời để gia nhập {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Bạn sắp sửa thu phí người tham gia một khoản {{amount, currency}}. Bạn có chắc chắn muốn tiếp tục?", "charge_card_dialog_body": "Bạn sắp sửa thu phí người tham gia một khoản {{amount, currency}}. Bạn có chắc chắn muốn tiếp tục?",
"charge_attendee": "Thu phí người tham gia một khoản {{amount, currency}}", "charge_attendee": "Thu phí người tham gia một khoản {{amount, currency}}",
@@ -1741,6 +1855,7 @@
"email_invite_team_bulk": "{{userCount}} người dùng đã được mời", "email_invite_team_bulk": "{{userCount}} người dùng đã được mời",
"error_collecting_card": "Lỗi khi thu thập thẻ", "error_collecting_card": "Lỗi khi thu thập thẻ",
"image_size_limit_exceed": "Ảnh tải lên không được vượt quá giới hạn kích cỡ 5mb", "image_size_limit_exceed": "Ảnh tải lên không được vượt quá giới hạn kích cỡ 5mb",
"unauthorized_workflow_error_message": "{{errorCode}}: Bạn không được uỷ quyền để bật hoặc tắt tiến độ công việc này",
"inline_embed": "Nhúng inline", "inline_embed": "Nhúng inline",
"load_inline_content": "Tải trực tiếp loại sự kiện của bạn ở dạng nội tuyến với nội dung khác trên website của bạn.", "load_inline_content": "Tải trực tiếp loại sự kiện của bạn ở dạng nội tuyến với nội dung khác trên website của bạn.",
"floating_pop_up_button": "Nút popup dạng nổi", "floating_pop_up_button": "Nút popup dạng nổi",
@@ -1760,7 +1875,69 @@
"connect_google_workspace": "Kết nối Google Workspace", "connect_google_workspace": "Kết nối Google Workspace",
"google_workspace_admin_tooltip": "Bạn phải là một Quản trị viên Không gian làm việc để dùng tính năng này", "google_workspace_admin_tooltip": "Bạn phải là một Quản trị viên Không gian làm việc để dùng tính năng này",
"first_event_type_webhook_description": "Tạo webhook đầu tiên của bạn cho loại sự kiện này", "first_event_type_webhook_description": "Tạo webhook đầu tiên của bạn cho loại sự kiện này",
"install_app_on": "Cài đặt ứng dụng trên",
"create_for": "Tạo cho", "create_for": "Tạo cho",
"setup_organization": "Thiết lập một Tổ chức",
"organization_banner_description": "Tạo một môi trường tại đó các nhóm của bạn có thể tạo những ứng dụng, tiến độ công việc và loại sự kiện mà có thể chia sẻ được, với chức năng đặt lịch dạng round-robin và tập thể.",
"organization_banner_title": "Quản lý các tổ chức có nhiều nhóm",
"set_up_your_organization": "Thiết lập tổ chức của bạn",
"organizations_description": "Tổ chức là môi trường chia sẻ tại đó các nhóm có thể tạo loại sự kiện, ứng dụng, tiến độ công việc, v. v. vốn được chia sẻ dùng chung.",
"must_enter_organization_name": "Cần phải nhập tên tổ chức",
"must_enter_organization_admin_email": "Cần phải nhập địa chỉ email của tổ chức",
"admin_email": "Địa chỉ email của tổ chức",
"admin_username": "Tên người dùng quản trị viên",
"organization_name": "Tên tổ chức",
"organization_url": "URL của tổ chức",
"organization_verify_header": "Xác minh email của tổ chức",
"organization_verify_email_body": "Vui lòng sử dụng mã bên dưới để xác minh địa chỉ email của bạn để tiếp tục thiết lập tổ chức của bạn.",
"additional_url_parameters": "Tham số URL bổ sung",
"about_your_organization": "Giới thiệu tổ chức của bạn",
"about_your_organization_description": "Tổ chức là môi trường chia sẻ tại đó bạn có thể tạo nhiều nhóm có thành viên chung, loại sự kiện chung, ứng dụng chung, tiến độ công việc chung, v.v..",
"create_your_teams": "Tạo nhóm của bạn",
"create_your_teams_description": "Bắt đầu đặt lịch cùng nhau bằng cách thêm thành viên nhóm bạn vào tổ chức",
"invite_organization_admins": "Mời những quản trị viên của tổ chức",
"invite_organization_admins_description": "Những quản trị viên này có quyền truy cập mọi nhóm trong tổ chức. Bạn có thể thêm quản trị viên và thành viên của nhóm sau đó.",
"set_a_password": "Đặt mật khẩu",
"set_a_password_description": "Thao tác này sẽ tạo một tài khoản người dùng mới với email của tổ chức và mật khẩu này.",
"organization_logo": "Logo của tổ chức",
"organization_about_description": "Một vài câu về tổ chức của bạn. Thông tin này sẽ xuất hiện trên trang hồ sơ công cộng của tổ chức.",
"ill_do_this_later": "Tôi sẽ làm sau",
"verify_your_email": "Xác minh email của bạn",
"enter_digit_code": "Nhập mã 6 chữ số mà chúng tôi đã gửi tới {{email}}",
"verify_email_organization": "Xác minh email của bạn để tạo một tổ chức",
"code_provided_invalid": "Mã cung cấp là mã không hợp lệ, hãy thử lại",
"email_already_used": "Email đã được dùng",
"organization_admin_invited_heading": "Bạn đã được mời để gia nhập {{orgName}}",
"organization_admin_invited_body": "Gia nhập nhóm của bạn tại {{orgName}} và bắt đầu tập trung vào cuộc họp, chứ không còn lo tạo ra cuộc họp!",
"duplicated_slugs_warning": "Những nhóm sau không thể tạo do có slug trùng lặp: {{slugs}}",
"team_names_empty": "Tên nhóm không được để trống",
"team_names_repeated": "Tên nhóm không được lặp lại",
"user_belongs_organization": "Người dùng thuộc về một nhóm",
"org_no_teams_yet": "Tổ chức này chưa có nhóm nào",
"org_no_teams_yet_description": "Nếu bạn là một quản trị viên, hãy bảo đảm tạo nhóm các nhóm cần được hiển thị tại đây.",
"set_up": "Thiết lập",
"set_up_your_profile": "Thiết lập hồ sơ của bạn",
"set_up_your_profile_description": "Hãy để mọi người biết bạn là ai trong {{orgName}}, và họ biết khi nhấp vào liên kết công cộng của bạn.",
"my_profile": "Hồ sơ của tôi",
"my_settings": "Cài đặt của tôi",
"crm": "CRM",
"messaging": "Nhắn tin",
"sender_id_info": "Tên hoặc số hiển thị ở chỗ người gửi SMS (một số quốc gia không cho phép ID người gửi dạng chữ lẫn số)",
"org_admins_can_create_new_teams": "Chỉ quản trị viên của tổ chức mới tạo được nhóm mới",
"google_new_spam_policy": "Chính sách spam mới của Google có thể ngăn bạn không cho nhận bất kì thông báo nào về email và lịch liên quan đến lịch hẹn này.",
"resolve": "Giải quyết",
"no_organization_slug": "Có lỗi khi tạo nhóm cho tổ chức này. Slug URL bị thiếu.",
"org_name": "Tên tổ chức",
"org_url": "URL của tổ chức",
"copy_link_org": "Sao chép liên kết đến tổ chức",
"404_the_org": "Tổ chức",
"404_the_team": "Nhóm",
"404_claim_entity_org": "Lấy tên miền phụ cho tổ chức của bạn",
"404_claim_entity_team": "Lấy nhóm này và bắt đầu quản lý lịch hẹn theo tập thể", "404_claim_entity_team": "Lấy nhóm này và bắt đầu quản lý lịch hẹn theo tập thể",
"insights_all_org_filter": "Tất cả" "insights_all_org_filter": "Tất cả",
"insights_team_filter": "Nhóm: {{teamName}}",
"insights_user_filter": "Người dùng: {{userName}}",
"insights_subtitle": "Xem số liệu của lịch hẹn ở mọi sự kiện của bạn",
"custom_plan": "Gói Tuỳ chỉnh",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -17,6 +17,7 @@
"verify_email_banner_body": "验证您的电子邮件地址以确保最佳的电子邮件和日历递送能力", "verify_email_banner_body": "验证您的电子邮件地址以确保最佳的电子邮件和日历递送能力",
"verify_email_email_header": "验证您的电子邮件地址", "verify_email_email_header": "验证您的电子邮件地址",
"verify_email_email_button": "验证电子邮件", "verify_email_email_button": "验证电子邮件",
"copy_somewhere_safe": "将此 API 密钥保存在安全的地方。您将无法再次查看它。",
"verify_email_email_body": "请点击下面的按钮来验证您的电子邮件地址。", "verify_email_email_body": "请点击下面的按钮来验证您的电子邮件地址。",
"verify_email_email_link_text": "如果您不喜欢点击按钮,请点击以下链接:", "verify_email_email_link_text": "如果您不喜欢点击按钮,请点击以下链接:",
"email_sent": "电子邮件已成功发送", "email_sent": "电子邮件已成功发送",
@@ -243,6 +244,8 @@
"all": "所有应用", "all": "所有应用",
"yours": "您的账户", "yours": "您的账户",
"available_apps": "可用应用", "available_apps": "可用应用",
"available_apps_lower_case": "可用的应用",
"available_apps_desc": "您尚未安装任何应用。在我们的<1>应用商店</1>中查看热门应用,并探索更多内容。",
"check_email_reset_password": "请检查您的邮箱,我们向您发送了一个重置密码的链接。", "check_email_reset_password": "请检查您的邮箱,我们向您发送了一个重置密码的链接。",
"finish": "完成", "finish": "完成",
"organization_general_description": "管理您的团队语言和时区的设置", "organization_general_description": "管理您的团队语言和时区的设置",
@@ -349,7 +352,7 @@
"no_meeting_found": "未找到会议", "no_meeting_found": "未找到会议",
"no_meeting_found_description": "此会议不存在。联系会议所有者获取更新后的链接。", "no_meeting_found_description": "此会议不存在。联系会议所有者获取更新后的链接。",
"no_status_bookings_yet": "暂无 {{status}} 预约", "no_status_bookings_yet": "暂无 {{status}} 预约",
"no_status_bookings_yet_description": "您没有{{status}}预约,{{description}}", "no_status_bookings_yet_description": "您没有 {{status}} 预约,{{description}}",
"event_between_users": "{{host}} 和 {{attendeeName}} 之间的 {{eventName}}", "event_between_users": "{{host}} 和 {{attendeeName}} 之间的 {{eventName}}",
"bookings": "预约", "bookings": "预约",
"booking_not_found": "找不到预约", "booking_not_found": "找不到预约",
@@ -399,35 +402,36 @@
"leverage_our_api": "利用我们的 API 来实现完全控制和高度定制。", "leverage_our_api": "利用我们的 API 来实现完全控制和高度定制。",
"create_webhook": "创建 Webhook", "create_webhook": "创建 Webhook",
"booking_cancelled": "预约已取消", "booking_cancelled": "预约已取消",
"booking_rescheduled": "预约已重新安排", "booking_rescheduled": "预约已改期",
"recording_ready": "录制内容下载链接就绪", "recording_ready": "录制内容下载链接就绪",
"booking_created": "预约已创建", "booking_created": "预约已创建",
"booking_rejected": "预约被拒绝", "booking_rejected": "预约被拒绝",
"booking_requested": "预约已请求", "booking_requested": "预约已请求",
"meeting_ended": "会议已结束", "meeting_ended": "会议已结束",
"form_submitted": "表格已提交", "form_submitted": "表格已提交",
"booking_paid": "预约已付款",
"event_triggers": "事件触发", "event_triggers": "事件触发",
"subscriber_url": "订阅者链接", "subscriber_url": "订阅者链接",
"create_new_webhook": "创建一个新的 webhook", "create_new_webhook": "创建一个新的 Webhook",
"webhooks": "Webhook", "webhooks": "Webhook",
"team_webhooks": "团队 Webhook", "team_webhooks": "团队 Webhook",
"create_new_webhook_to_account": "为您的账户创建一个新的Webhook", "create_new_webhook_to_account": "为您的账户创建一个新的 Webhook",
"new_webhook": "新建 Webhook", "new_webhook": "新建 Webhook",
"receive_cal_meeting_data": "当安排或取消活动后,在指定链接实时接收 {{appName}} 会议数据。", "receive_cal_meeting_data": "当安排或取消活动后,在指定链接实时接收 {{appName}} 会议数据。",
"receive_cal_event_meeting_data": "当安排或取消此活动后,在指定链接实时接收 {{appName}} 会议数据。", "receive_cal_event_meeting_data": "当安排或取消此活动后,在指定链接实时接收 {{appName}} 会议数据。",
"responsive_fullscreen_iframe": "全屏响应式iframe", "responsive_fullscreen_iframe": "全屏响应式 iframe",
"loading": "加载中...", "loading": "加载中...",
"deleting": "正在删除...", "deleting": "正在删除...",
"standard_iframe": "标准 iframe", "standard_iframe": "标准 iframe",
"developer": "开发人员", "developer": "开发人员",
"manage_developer_settings": "管理您的开发人员设置。", "manage_developer_settings": "管理您的开发人员设置。",
"iframe_embed": "嵌入 iframe", "iframe_embed": "嵌入 iframe",
"embed_calcom": "用最简单的方式将{{appName}}嵌入您的网站", "embed_calcom": "用最简单的方式将 {{appName}} 嵌入您的网站",
"integrate_using_embed_or_webhooks": "将我们的功能嵌入式集成进您的网站,或者使用自定义Webhook获得实时预约信息。", "integrate_using_embed_or_webhooks": "将我们的功能嵌入式集成进您的网站,或者使用自定义Webhook获得实时预约信息。",
"schedule_a_meeting": "安排会议", "schedule_a_meeting": "安排会议",
"view_and_manage_billing_details": "查看和管理您的账单详情", "view_and_manage_billing_details": "查看和管理您的账单详情",
"view_and_edit_billing_details": "查看和编辑您的账单详情,以及取消订阅。", "view_and_edit_billing_details": "查看和编辑您的账单详情,以及取消订阅。",
"go_to_billing_portal": "转到账单门户网站", "go_to_billing_portal": "前往付费入口",
"need_anything_else": "还有其他需要?", "need_anything_else": "还有其他需要?",
"further_billing_help": "如果您在支付帐单时需要任何进一步的帮助,我们的支持团队会给您提供帮助。", "further_billing_help": "如果您在支付帐单时需要任何进一步的帮助,我们的支持团队会给您提供帮助。",
"contact": "联系", "contact": "联系",
@@ -706,8 +710,8 @@
"upgrade_to_flexible_pro_message": "您的团队中有没有位置的成员。升级到专业版来获得更多位置。", "upgrade_to_flexible_pro_message": "您的团队中有没有位置的成员。升级到专业版来获得更多位置。",
"changed_team_billing_info": "自2022年1月起,我们将按每个位置向团队成员收取费用。 您的团队中免费获得专业版的成员现在正在进行为期14天的试用。 试用期结束后,这些成员将在您的团队中隐藏,除非您现在升级到专业版。", "changed_team_billing_info": "自2022年1月起,我们将按每个位置向团队成员收取费用。 您的团队中免费获得专业版的成员现在正在进行为期14天的试用。 试用期结束后,这些成员将在您的团队中隐藏,除非您现在升级到专业版。",
"create_manage_teams_collaborative": "创建并管理团队以使用协作功能。", "create_manage_teams_collaborative": "创建并管理团队以使用协作功能。",
"only_available_on_pro_plan": "此功能仅在Pro套餐中可用", "only_available_on_pro_plan": "此功能仅在 Pro 套餐中可用",
"remove_cal_branding_description": "若想从您的预约页面中去掉{{appName}}品牌标志,您需要升级到专业版账户。", "remove_cal_branding_description": "若想从您的预约页面中去掉 {{appName}} 的品牌标志,您需要升级到专业版账户。",
"edit_profile_info_description": "编辑您的个人资料,在您的预约链接上显示。", "edit_profile_info_description": "编辑您的个人资料,在您的预约链接上显示。",
"change_email_tip": "您可能需要注销并重新登录才能使更改生效。", "change_email_tip": "您可能需要注销并重新登录才能使更改生效。",
"little_something_about": "一些关于你自己的描述。", "little_something_about": "一些关于你自己的描述。",
@@ -767,12 +771,12 @@
"set_link_meeting": "设置会议链接", "set_link_meeting": "设置会议链接",
"cal_invitee_phone_number_scheduling": "{{appName}} 将要求您的受邀者在安排时间之前提供电话号码。", "cal_invitee_phone_number_scheduling": "{{appName}} 将要求您的受邀者在安排时间之前提供电话号码。",
"cal_provide_google_meet_location": "{{appName}} 将提供 Google Meet 位置。", "cal_provide_google_meet_location": "{{appName}} 将提供 Google Meet 位置。",
"cal_provide_zoom_meeting_url": "{{appName}}将提供Zoom会议链接", "cal_provide_zoom_meeting_url": "{{appName}}将提供 Zoom 会议链接",
"cal_provide_tandem_meeting_url": "{{appName}} 将提供Tandem会议链接", "cal_provide_tandem_meeting_url": "{{appName}} 将提供 Tandem 会议链接",
"cal_provide_video_meeting_url": "{{appName}}将提供Daily视频会议链接", "cal_provide_video_meeting_url": "{{appName}}将提供 Daily 视频会议链接",
"cal_provide_jitsi_meeting_url": "{{appName}} 将提供Jitsi Meet视频会议链接", "cal_provide_jitsi_meeting_url": "{{appName}} 将提供 Jitsi Meet 视频会议链接",
"cal_provide_huddle01_meeting_url": "{{appName}} 将提供Huddle01 Web3视频会议链接", "cal_provide_huddle01_meeting_url": "{{appName}} 将提供 Huddle01 web3 视频会议链接",
"cal_provide_teams_meeting_url": "{{appName}} 将提供 MS Teams 会议 URL。注意: 必须拥有工作或学校帐户", "cal_provide_teams_meeting_url": "{{appName}} 将提供 MS Teams 会议 URL。注意: 须拥有工作或学校帐户",
"require_payment": "需要付款", "require_payment": "需要付款",
"you_need_to_add_a_name": "您需要添加名称", "you_need_to_add_a_name": "您需要添加名称",
"commission_per_transaction": "每笔交易的佣金", "commission_per_transaction": "每笔交易的佣金",
@@ -846,7 +850,7 @@
"user_away_description": "您试图预约的人已将自己置于离开状态,因此不接受新预约。", "user_away_description": "您试图预约的人已将自己置于离开状态,因此不接受新预约。",
"meet_people_with_the_same_tokens": "会见使用相同令牌的人", "meet_people_with_the_same_tokens": "会见使用相同令牌的人",
"only_book_people_and_allow": "仅和拥有相同令牌、分布式自治组织或非同质化代币的人的预约。", "only_book_people_and_allow": "仅和拥有相同令牌、分布式自治组织或非同质化代币的人的预约。",
"account_created_with_identity_provider": "您的账户是使用身份提供商创建的。", "account_created_with_identity_provider": "您的账户是使用身份提供方创建的。",
"account_managed_by_identity_provider": "您的账户由 {{provider}} 管理", "account_managed_by_identity_provider": "您的账户由 {{provider}} 管理",
"account_managed_by_identity_provider_description": "要更改您的电子邮件,密码,启用两步验证及更多功能,请访问您的 {{provider}} 账户设置。", "account_managed_by_identity_provider_description": "要更改您的电子邮件,密码,启用两步验证及更多功能,请访问您的 {{provider}} 账户设置。",
"signin_with_google": "使用Google登录", "signin_with_google": "使用Google登录",
@@ -1465,8 +1469,8 @@
"error_editing_availability": "编辑可预约时间时出错", "error_editing_availability": "编辑可预约时间时出错",
"dont_have_permission": "您无权访问此资源。", "dont_have_permission": "您无权访问此资源。",
"saml_config": "SAML", "saml_config": "SAML",
"saml_configuration_placeholder": "请将从身份提供商获取的 SAML metadata 粘贴到这里", "saml_configuration_placeholder": "请将从身份提供方获取的 SAML metadata 粘贴到这里",
"saml_email_required": "请输入您的邮箱,以便我们找到您的 SAML 身份提供商", "saml_email_required": "请输入您的邮箱,以便我们找到您的 SAML 身份提供方",
"saml_sp_title": "服务提供商详细信息", "saml_sp_title": "服务提供商详细信息",
"saml_sp_description": "您的身份提供程序 (IdP) 将要求您提供以下详细信息以完成 SAML 应用程序配置。", "saml_sp_description": "您的身份提供程序 (IdP) 将要求您提供以下详细信息以完成 SAML 应用程序配置。",
"saml_sp_acs_url": "ACS 链接", "saml_sp_acs_url": "ACS 链接",
@@ -1939,5 +1943,5 @@
"insights_user_filter": "用户:{{userName}}", "insights_user_filter": "用户:{{userName}}",
"insights_subtitle": "查看您的活动的预约洞察", "insights_subtitle": "查看您的活动的预约洞察",
"custom_plan": "自定义计划", "custom_plan": "自定义计划",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在上面这里添加新的字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在此上方添加您的新字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+106 -18
View File
@@ -1,6 +1,6 @@
{ {
"identity_provider": "身分提供者", "identity_provider": "身分提供者",
"trial_days_left": "試用 PRO 方案還有 $t(day, {\"count\": {{days}} })", "trial_days_left": "您的 PRO 試用期還有 $t(day, {\"count\": {{days}} }) 到期",
"day_one": "{{count}} 天", "day_one": "{{count}} 天",
"day_other": "{{count}} 天", "day_other": "{{count}} 天",
"second_one": "{{count}} 秒", "second_one": "{{count}} 秒",
@@ -306,9 +306,9 @@
"password_has_been_reset_login": "密碼已經重置。現在即可使用新建立的密碼登入。", "password_has_been_reset_login": "密碼已經重置。現在即可使用新建立的密碼登入。",
"layout": "版面", "layout": "版面",
"bookerlayout_default_title": "預設檢視", "bookerlayout_default_title": "預設檢視",
"bookerlayout_description": "您可以選擇多個版面,以便您的預約者切換檢視。", "bookerlayout_description": "您可以選擇多個版面,以便預約者切換檢視。",
"bookerlayout_user_settings_title": "預約版面", "bookerlayout_user_settings_title": "預約版面",
"bookerlayout_user_settings_description": "您可以選擇多個版面,以便您的預約者切換檢視。您可根據不同活動來覆寫此設定。", "bookerlayout_user_settings_description": "您可以選擇多個版面,以便預約者切換檢視。您可根據不同活動來覆寫此設定。",
"bookerlayout_month_view": "月", "bookerlayout_month_view": "月",
"bookerlayout_week_view": "週", "bookerlayout_week_view": "週",
"bookerlayout_column_view": "欄", "bookerlayout_column_view": "欄",
@@ -349,7 +349,7 @@
"no_meeting_found": "找不到會議", "no_meeting_found": "找不到會議",
"no_meeting_found_description": "會議不存在。請聯繫會議主持人取得新連結。", "no_meeting_found_description": "會議不存在。請聯繫會議主持人取得新連結。",
"no_status_bookings_yet": "暫無 {{status}} 的預約", "no_status_bookings_yet": "暫無 {{status}} 的預約",
"no_status_bookings_yet_description": "沒有{{status}}的預約。{{description}}", "no_status_bookings_yet_description": "沒有 {{status}} 的預約。{{description}}",
"event_between_users": "{{host}} 和 {{attendeeName}} 的 {{eventName}}", "event_between_users": "{{host}} 和 {{attendeeName}} 的 {{eventName}}",
"bookings": "預約", "bookings": "預約",
"booking_not_found": "找不到預約", "booking_not_found": "找不到預約",
@@ -398,7 +398,7 @@
"browse_api_documentation": "瀏覽 API 文件", "browse_api_documentation": "瀏覽 API 文件",
"leverage_our_api": "請充分利用 API 徹底掌握與客製化。", "leverage_our_api": "請充分利用 API 徹底掌握與客製化。",
"create_webhook": "建立 Webhook", "create_webhook": "建立 Webhook",
"booking_cancelled": "預約已取消", "booking_cancelled": "已取消預約",
"booking_rescheduled": "已重新安排預約", "booking_rescheduled": "已重新安排預約",
"recording_ready": "錄製內容下載連結已就緒", "recording_ready": "錄製內容下載連結已就緒",
"booking_created": "已建立預約", "booking_created": "已建立預約",
@@ -411,17 +411,17 @@
"create_new_webhook": "建立新的 Webhook", "create_new_webhook": "建立新的 Webhook",
"webhooks": "Webhook", "webhooks": "Webhook",
"team_webhooks": "團隊 Webhook", "team_webhooks": "團隊 Webhook",
"create_new_webhook_to_account": "建立這個帳號的新 Webhook", "create_new_webhook_to_account": "為您的帳號建立一個的新 Webhook",
"new_webhook": "新 Webhook", "new_webhook": "新 Webhook",
"receive_cal_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。", "receive_cal_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。",
"receive_cal_event_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。", "receive_cal_event_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。",
"responsive_fullscreen_iframe": "全螢幕響應式 Iframe", "responsive_fullscreen_iframe": "全螢幕響應式 iframe",
"loading": "讀取中...", "loading": "讀取中...",
"deleting": "正在刪除......", "deleting": "正在刪除......",
"standard_iframe": "標準 Iframe", "standard_iframe": "標準 iframe",
"developer": "開發人員", "developer": "開發人員",
"manage_developer_settings": "管理您的開發人員設定。", "manage_developer_settings": "管理您的開發人員設定。",
"iframe_embed": "嵌入式 Iframe", "iframe_embed": "嵌入式 iframe",
"embed_calcom": "在網站上嵌入 {{appName}} 最簡單的方法。", "embed_calcom": "在網站上嵌入 {{appName}} 最簡單的方法。",
"integrate_using_embed_or_webhooks": "使用嵌入的方法整合進網站,或是以自訂 Webhook 的方式獲取即時預約資訊。", "integrate_using_embed_or_webhooks": "使用嵌入的方法整合進網站,或是以自訂 Webhook 的方式獲取即時預約資訊。",
"schedule_a_meeting": "預定會議", "schedule_a_meeting": "預定會議",
@@ -846,7 +846,7 @@
"user_away_description": "試圖預約的人已經設定為離開狀態,因此不接受新預約。", "user_away_description": "試圖預約的人已經設定為離開狀態,因此不接受新預約。",
"meet_people_with_the_same_tokens": "認識有相同 Token 的人", "meet_people_with_the_same_tokens": "認識有相同 Token 的人",
"only_book_people_and_allow": "只預約/接受預約有相同 Token、DAO 或 NFT 的人。", "only_book_people_and_allow": "只預約/接受預約有相同 Token、DAO 或 NFT 的人。",
"account_created_with_identity_provider": "帳號是使用 Identity Provider 建立的。", "account_created_with_identity_provider": "帳號是使用身分提供者建立的。",
"account_managed_by_identity_provider": "帳號歸 {{provider}} 管轄", "account_managed_by_identity_provider": "帳號歸 {{provider}} 管轄",
"account_managed_by_identity_provider_description": "要更改電子郵件、密碼、兩階段認證⋯⋯等,請造訪 {{provider}} 的帳號設定。", "account_managed_by_identity_provider_description": "要更改電子郵件、密碼、兩階段認證⋯⋯等,請造訪 {{provider}} 的帳號設定。",
"signin_with_google": "透過 Google 登入", "signin_with_google": "透過 Google 登入",
@@ -979,7 +979,7 @@
"confirm_delete_api_key": "撤銷此 API 金鑰", "confirm_delete_api_key": "撤銷此 API 金鑰",
"revoke_api_key": "撤銷 API 金鑰", "revoke_api_key": "撤銷 API 金鑰",
"api_key_copied": "已複製 API 金鑰!", "api_key_copied": "已複製 API 金鑰!",
"api_key_expires_on": "API 金鑰的到期時間為", "api_key_expires_on": "API 金鑰的到期時間",
"delete_api_key_confirm_title": "確定要將此 API 金鑰從您的帳號永久移除?", "delete_api_key_confirm_title": "確定要將此 API 金鑰從您的帳號永久移除?",
"copy": "複製", "copy": "複製",
"expire_date": "到期日", "expire_date": "到期日",
@@ -1003,7 +1003,7 @@
"user_impersonation_description": "允許支援團隊以您的身分暫時登入,以便快速解決您通報給我們的任何問題。", "user_impersonation_description": "允許支援團隊以您的身分暫時登入,以便快速解決您通報給我們的任何問題。",
"team_impersonation_description": "允許您的團隊擁有者/管理員暫時以您的身分登入。", "team_impersonation_description": "允許您的團隊擁有者/管理員暫時以您的身分登入。",
"make_team_private": "設為私人團隊", "make_team_private": "設為私人團隊",
"make_team_private_description": "啟用此設定時,您的團隊成員將無法查看其他團隊成員。", "make_team_private_description": "啟用此設定時,團隊成員將無法查看其他團隊成員。",
"you_cannot_see_team_members": "您無法查看私人團隊的所有團隊成員。", "you_cannot_see_team_members": "您無法查看私人團隊的所有團隊成員。",
"allow_booker_to_select_duration": "允許預約者選擇時間長度", "allow_booker_to_select_duration": "允許預約者選擇時間長度",
"impersonate_user_tip": "此功能的所有使用已經過稽核。", "impersonate_user_tip": "此功能的所有使用已經過稽核。",
@@ -1291,7 +1291,7 @@
"conferencing_description": "為您的會議加入最愛的視訊會議應用程式", "conferencing_description": "為您的會議加入最愛的視訊會議應用程式",
"add_conferencing_app": "新增會議應用程式", "add_conferencing_app": "新增會議應用程式",
"password_description": "管理帳號密碼設定", "password_description": "管理帳號密碼設定",
"set_up_two_factor_authentication": "設定您的兩階段驗證", "set_up_two_factor_authentication": "設定兩階段驗證",
"we_just_need_basic_info": "我們只需要一些基本資料,就能完成您的個人資料設定。", "we_just_need_basic_info": "我們只需要一些基本資料,就能完成您的個人資料設定。",
"skip": "略過", "skip": "略過",
"do_this_later": "稍後再說", "do_this_later": "稍後再說",
@@ -1335,7 +1335,7 @@
"event_one": "活動", "event_one": "活動",
"event_other": "活動", "event_other": "活動",
"profile_team_description": "管理團隊資料設定", "profile_team_description": "管理團隊資料設定",
"profile_org_description": "管理您的組織資料設定", "profile_org_description": "管理組織資料設定",
"members_team_description": "群組中的使用者", "members_team_description": "群組中的使用者",
"organization_description": "管理您組織的管理者和成員", "organization_description": "管理您組織的管理者和成員",
"team_url": "團隊網址", "team_url": "團隊網址",
@@ -1378,7 +1378,7 @@
"routing_forms_send_email_owner": "傳送電子郵件給擁有者", "routing_forms_send_email_owner": "傳送電子郵件給擁有者",
"routing_forms_send_email_owner_description": "表單提交後傳送電子郵件給擁有者", "routing_forms_send_email_owner_description": "表單提交後傳送電子郵件給擁有者",
"add_new_form": "新增新表單", "add_new_form": "新增新表單",
"add_new_team_form": "為您的團隊新增表單", "add_new_team_form": "為團隊新增表單",
"create_your_first_route": "建立第一份引導表單", "create_your_first_route": "建立第一份引導表單",
"route_to_the_right_person": "根據表單回覆引導至合適的人員", "route_to_the_right_person": "根據表單回覆引導至合適的人員",
"form_description": "建立您的表單來引導預約者", "form_description": "建立您的表單來引導預約者",
@@ -1465,8 +1465,8 @@
"error_editing_availability": "編輯開放時間時發生錯誤", "error_editing_availability": "編輯開放時間時發生錯誤",
"dont_have_permission": "您沒有權限存取此資源。", "dont_have_permission": "您沒有權限存取此資源。",
"saml_config": "SAML", "saml_config": "SAML",
"saml_configuration_placeholder": "請把 Identity Provider 的 SAML Metadata 貼到這裡。", "saml_configuration_placeholder": "請把身分提供者的 SAML Metadata 貼到這裡。",
"saml_email_required": "請輸入讓我們可以找到 SAML Identity Provider 的電子郵件", "saml_email_required": "請輸入讓我們可以找到 SAML 身分提供者的電子郵件",
"saml_sp_title": "服務供應方詳細資訊", "saml_sp_title": "服務供應方詳細資訊",
"saml_sp_description": "您的 Identity Provider (IdP) 會要求您提供下列詳細資料,以完成 SAML 應用程式設定。", "saml_sp_description": "您的 Identity Provider (IdP) 會要求您提供下列詳細資料,以完成 SAML 應用程式設定。",
"saml_sp_acs_url": "ACS 網址", "saml_sp_acs_url": "ACS 網址",
@@ -1672,6 +1672,8 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "無工作流程", "no_workflows": "無工作流程",
"change_filter": "變更篩選條件,即可查看您個人和團隊的工作流程。", "change_filter": "變更篩選條件,即可查看您個人和團隊的工作流程。",
"change_filter_common": "變更篩選條件以查看結果。",
"no_results_for_filter": "此篩選條件找不到結果",
"recommended_next_steps": "建議的後續步驟", "recommended_next_steps": "建議的後續步驟",
"create_a_managed_event": "建立受管活動類型", "create_a_managed_event": "建立受管活動類型",
"meetings_are_better_with_the_right": "找對團隊成員開會,開會更有效率。立即邀請他們。", "meetings_are_better_with_the_right": "找對團隊成員開會,開會更有效率。立即邀請他們。",
@@ -1682,7 +1684,9 @@
"no_longer_attending": "您不再參加這個活動", "no_longer_attending": "您不再參加這個活動",
"attendee_no_longer_attending_subject": "一位與會者不再參加 {{date}} 的 {{title}}", "attendee_no_longer_attending_subject": "一位與會者不再參加 {{date}} 的 {{title}}",
"attendee_no_longer_attending": "一位與會者不再參加您的活動", "attendee_no_longer_attending": "一位與會者不再參加您的活動",
"attendee_no_longer_attending_subtitle": "{{name}} 已取消,這代表此時段空出了一個座位",
"create_event_on": "活動建立日期", "create_event_on": "活動建立日期",
"create_routing_form_on": "建立引導表單於",
"default_app_link_title": "設定預設應用程式連結", "default_app_link_title": "設定預設應用程式連結",
"default_app_link_description": "設定預設應用程式連結,即可讓所有全新建立的活動類型使用您設定的應用程式連結。", "default_app_link_description": "設定預設應用程式連結,即可讓所有全新建立的活動類型使用您設定的應用程式連結。",
"organizer_default_conferencing_app": "主辦者的預設應用程式", "organizer_default_conferencing_app": "主辦者的預設應用程式",
@@ -1692,6 +1696,7 @@
"booking_questions_title": "預約問題", "booking_questions_title": "預約問題",
"booking_questions_description": "自訂預約頁面上的提問問題", "booking_questions_description": "自訂預約頁面上的提問問題",
"add_a_booking_question": "新增問題", "add_a_booking_question": "新增問題",
"identifier": "識別項",
"duplicate_email": "電子郵件重複", "duplicate_email": "電子郵件重複",
"booking_with_payment_cancelled": "無法再為此活動付費", "booking_with_payment_cancelled": "無法再為此活動付費",
"booking_with_payment_cancelled_already_paid": "此預約付款的退款已在辦理中。", "booking_with_payment_cancelled_already_paid": "此預約付款的退款已在辦理中。",
@@ -1702,6 +1707,7 @@
"show_on_booking_page": "在預約頁面上顯示", "show_on_booking_page": "在預約頁面上顯示",
"get_started_zapier_templates": "開始使用 Zapier 範本", "get_started_zapier_templates": "開始使用 Zapier 範本",
"team_is_unpublished": "已取消發佈 {{team}}", "team_is_unpublished": "已取消發佈 {{team}}",
"team_is_unpublished_description": "此 {{entity}} 連結目前無法使用。請聯絡 {{entity}} 擁有者,或請對方發佈。",
"team_member": "團隊成員", "team_member": "團隊成員",
"a_routing_form": "引導表單", "a_routing_form": "引導表單",
"form_description_placeholder": "表單說明", "form_description_placeholder": "表單說明",
@@ -1731,13 +1737,16 @@
"spot_popular_event_types": "找出熱門活動類型", "spot_popular_event_types": "找出熱門活動類型",
"spot_popular_event_types_description": "查看哪種活動類型的點閱次數及預約次數最多", "spot_popular_event_types_description": "查看哪種活動類型的點閱次數及預約次數最多",
"no_responses_yet": "還沒有回應", "no_responses_yet": "還沒有回應",
"no_routes_defined": "未定義任何引導路由",
"this_will_be_the_placeholder": "此處會是佔位符", "this_will_be_the_placeholder": "此處會是佔位符",
"error_booking_event": "預約活動時發生錯誤,請重新整理頁面然後再試一次",
"timeslot_missing_title": "未選擇任何時段", "timeslot_missing_title": "未選擇任何時段",
"timeslot_missing_description": "請選擇要預約活動的時段。", "timeslot_missing_description": "請選擇要預約活動的時段。",
"timeslot_missing_cta": "選擇時段", "timeslot_missing_cta": "選擇時段",
"switch_monthly": "切換至每月檢視", "switch_monthly": "切換至每月檢視",
"switch_weekly": "切換至每週檢視", "switch_weekly": "切換至每週檢視",
"switch_multiday": "切換至每日檢視", "switch_multiday": "切換至每日檢視",
"switch_columnview": "切換至欄檢視",
"num_locations": "{{num}} 個地點選項", "num_locations": "{{num}} 個地點選項",
"select_on_next_step": "於下一步選擇", "select_on_next_step": "於下一步選擇",
"this_meeting_has_not_started_yet": "此會議尚未開始", "this_meeting_has_not_started_yet": "此會議尚未開始",
@@ -1776,6 +1785,7 @@
"managed_event_dialog_title_one": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?", "managed_event_dialog_title_one": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?",
"managed_event_dialog_title_other": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?", "managed_event_dialog_title_other": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?",
"managed_event_dialog_information_one": "<strong>{{names}}</strong> 已在使用 <strong>/{{slug}}</strong> 網址。", "managed_event_dialog_information_one": "<strong>{{names}}</strong> 已在使用 <strong>/{{slug}}</strong> 網址。",
"managed_event_dialog_information_other": "<strong>{{names}}</strong> 已在使用 <strong>/{{slug}}</strong> 網址。",
"managed_event_dialog_clarification": "如果您選擇取代,我們會通知他們;如果不想覆寫既有網址,請返回並移除。", "managed_event_dialog_clarification": "如果您選擇取代,我們會通知他們;如果不想覆寫既有網址,請返回並移除。",
"review_event_type": "查看活動類型", "review_event_type": "查看活動類型",
"looking_for_more_analytics": "在找更多分析嗎?", "looking_for_more_analytics": "在找更多分析嗎?",
@@ -1791,12 +1801,14 @@
"least_booked_members": "最少預約的成員", "least_booked_members": "最少預約的成員",
"events_created": "已建立的活動", "events_created": "已建立的活動",
"events_completed": "已完成的活動", "events_completed": "已完成的活動",
"events_cancelled": "已取消的活動",
"events_rescheduled": "已重新預定的活動", "events_rescheduled": "已重新預定的活動",
"from_last_period": "從上一個時段", "from_last_period": "從上一個時段",
"from_to_date_period": "開始:{{startDate}} 結束:{{endDate}}", "from_to_date_period": "開始:{{startDate}} 結束:{{endDate}}",
"redirect_url_warning": "加入重新導向功能會停用成功頁面。請務必在自訂的成功頁面中註明「預約已確認」。", "redirect_url_warning": "加入重新導向功能會停用成功頁面。請務必在自訂的成功頁面中註明「預約已確認」。",
"event_trends": "活動趨勢", "event_trends": "活動趨勢",
"clear_filters": "清除篩選條件", "clear_filters": "清除篩選條件",
"clear": "清除",
"hold": "保留", "hold": "保留",
"on_booking_option": "預約時收款", "on_booking_option": "預約時收款",
"hold_option": "收取缺席費", "hold_option": "收取缺席費",
@@ -1823,6 +1835,18 @@
"complete_your_booking": "完成您的預約", "complete_your_booking": "完成您的預約",
"complete_your_booking_subject": "完成您的預約:{{date}} 的 {{title}}", "complete_your_booking_subject": "完成您的預約:{{date}} 的 {{title}}",
"confirm_your_details": "確認詳細資料", "confirm_your_details": "確認詳細資料",
"copy_invite_link": "複製邀請連結",
"edit_invite_link": "編輯連結設定",
"invite_link_copied": "邀請連結已複製",
"invite_link_deleted": "邀請連結已刪除",
"invite_link_updated": "邀請連結設定已儲存",
"link_expires_after": "連結設定效期…",
"one_day": "1 天",
"seven_days": "7 天",
"thirty_days": "30 天",
"three_months": "3 個月",
"one_year": "1 年",
"team_invite_received": "您已獲邀加入 {{teamName}}",
"currency_string": "{{amount, currency}}", "currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "您即將向與會者收取 {{amount, currency}}。確定要繼續嗎?", "charge_card_dialog_body": "您即將向與會者收取 {{amount, currency}}。確定要繼續嗎?",
"charge_attendee": "向與會者收取 {{amount, currency}}", "charge_attendee": "向與會者收取 {{amount, currency}}",
@@ -1831,6 +1855,7 @@
"email_invite_team_bulk": "已邀請 {{userCount}} 位使用者", "email_invite_team_bulk": "已邀請 {{userCount}} 位使用者",
"error_collecting_card": "卡片發生錯誤", "error_collecting_card": "卡片發生錯誤",
"image_size_limit_exceed": "上傳的圖片大小不得超過 5MB 限制", "image_size_limit_exceed": "上傳的圖片大小不得超過 5MB 限制",
"unauthorized_workflow_error_message": "{{errorCode}}:您未獲得授權,無法啟用或停用此工作流程",
"inline_embed": "內嵌式嵌入", "inline_embed": "內嵌式嵌入",
"load_inline_content": "直接載入您的活動類型及內嵌在其他網站的內容。", "load_inline_content": "直接載入您的活動類型及內嵌在其他網站的內容。",
"floating_pop_up_button": "浮動式彈出按鈕", "floating_pop_up_button": "浮動式彈出按鈕",
@@ -1850,6 +1875,69 @@
"connect_google_workspace": "連接 Google Workspace", "connect_google_workspace": "連接 Google Workspace",
"google_workspace_admin_tooltip": "您必須是 Workspace 管理員才能使用此功能", "google_workspace_admin_tooltip": "您必須是 Workspace 管理員才能使用此功能",
"first_event_type_webhook_description": "為此活動類型建立第一個 Webhook", "first_event_type_webhook_description": "為此活動類型建立第一個 Webhook",
"install_app_on": "安裝應用程式於",
"create_for": "建立", "create_for": "建立",
"insights_all_org_filter": "所有應用程式" "setup_organization": "設定組織",
"organization_banner_description": "建立環境,供團隊利用輪流制和全體預定功能建立共用的應用程式、工作流程和活動類型。",
"organization_banner_title": "管理有多個團隊的組織",
"set_up_your_organization": "設定您的組織",
"organizations_description": "團隊可在組織這個共用環境中建立共用的活動類型、應用程式、工作流程等。",
"must_enter_organization_name": "必須輸入組織名稱",
"must_enter_organization_admin_email": "必須輸入您的組織電子郵件地址",
"admin_email": "您的組織電子郵件地址",
"admin_username": "管理員使用者名稱",
"organization_name": "組織名稱",
"organization_url": "組織網址",
"organization_verify_header": "驗證您的組織電子郵件",
"organization_verify_email_body": "請使用以下驗證碼驗證您的電子郵件地址,以便繼續設定您的組織。",
"additional_url_parameters": "其他網址參數",
"about_your_organization": "關於您的組織",
"about_your_organization_description": "您可在組織這個共用環境中建立多個團隊,包括共用成員、活動類型、應用程式、工作流程等。",
"create_your_teams": "建立您的團隊",
"create_your_teams_description": "將團隊成員新增到組織,開始一起排程",
"invite_organization_admins": "邀請組織管理員",
"invite_organization_admins_description": "這些管理員將可存取組織中的所有團隊。您可稍後再新增團隊管理員和成員。",
"set_a_password": "設定密碼",
"set_a_password_description": "這麼做會使用貴組織電子郵件和此密碼建立新的使用者帳戶。",
"organization_logo": "組織標誌",
"organization_about_description": "請提供關於組織的簡介,這會顯示在組織的公開簡介網頁上。",
"ill_do_this_later": "之後再說",
"verify_your_email": "驗證電子郵件",
"enter_digit_code": "輸入我們傳送至 {{email}} 的 6 位數驗證碼",
"verify_email_organization": "驗證您的電子郵件,以建立組織",
"code_provided_invalid": "提供的驗證碼無效,再試一次",
"email_already_used": "電子郵件已有人使用",
"organization_admin_invited_heading": "您已獲邀加入 {{orgName}}",
"organization_admin_invited_body": "加入您在 {{orgName}} 的團隊,開始專注於會議本身,不必費心於會議的前置作業!",
"duplicated_slugs_warning": "由於重複的 slugs,下列團隊無法建立:{{slugs}}",
"team_names_empty": "團隊名稱不得留空",
"team_names_repeated": "團隊名稱不得重複",
"user_belongs_organization": "使用者屬於組織",
"org_no_teams_yet": "此組織尚未有團隊",
"org_no_teams_yet_description": "若您是管理員,請務必建立團隊,團隊才會顯示在這裡。",
"set_up": "設定",
"set_up_your_profile": "設定個人資料",
"set_up_your_profile_description": "向大家介紹您在 {{orgName}} 擔任的職務,以及他們何時可以使用您的公開連結。",
"my_profile": "我的個人資料",
"my_settings": "我的設定",
"crm": "CRM",
"messaging": "傳訊",
"sender_id_info": "顯示為簡訊傳送者的名稱或電話號碼 (部分國家/地區不允許英數字元的傳送者 ID)",
"org_admins_can_create_new_teams": "只有組織管理員才能建立新團隊",
"google_new_spam_policy": "Google 新的垃圾郵件政策可能會使您收不到關於此預約的任何電子郵件和行事曆通知。",
"resolve": "解決",
"no_organization_slug": "為此組織建立團隊時發生錯誤。缺少網址 slug。",
"org_name": "組織名稱",
"org_url": "組織網址",
"copy_link_org": "複製組織連結",
"404_the_org": "組織",
"404_the_team": "團隊",
"404_claim_entity_org": "認領組織的子網域",
"404_claim_entity_team": "認領此團隊並開始共同管理行程表",
"insights_all_org_filter": "所有應用程式",
"insights_team_filter": "團隊:{{teamName}}",
"insights_user_filter": "使用者:{{userName}}",
"insights_subtitle": "查看所有活動的預約洞見",
"custom_plan": "自訂方案",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在此上方添加您的新字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -33,6 +33,7 @@ it("can find lucky user with maximize availability", async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
prismaMock.user.findMany.mockResolvedValue(users); prismaMock.user.findMany.mockResolvedValue(users);
prismaMock.booking.findMany.mockResolvedValue([]);
await expect( await expect(
getLuckyUser("MAXIMIZE_AVAILABILITY", { getLuckyUser("MAXIMIZE_AVAILABILITY", {
+1
View File
@@ -77,6 +77,7 @@
"@deploysentinel/playwright": "^0.3.3", "@deploysentinel/playwright": "^0.3.3",
"@playwright/test": "^1.31.2", "@playwright/test": "^1.31.2",
"@snaplet/copycat": "^0.3.0", "@snaplet/copycat": "^0.3.0",
"@testing-library/jest-dom": "^5.16.5",
"@types/dompurify": "^2.4.0", "@types/dompurify": "^2.4.0",
"c8": "^7.13.0", "c8": "^7.13.0",
"dotenv-checker": "^1.1.5", "dotenv-checker": "^1.1.5",
+22 -9
View File
@@ -38,27 +38,38 @@ export default function AppCard({
return ( return (
<div <div
className={classNames( className={classNames(
"border-subtle mb-4", "border-subtle",
app.isInstalled ? "mt-2" : "mt-6", app?.isInstalled && "mb-4 rounded-md border",
"rounded-md border",
!app.enabled && "grayscale" !app.enabled && "grayscale"
)}> )}>
<div className={classNames(app.isInstalled ? "p-4 text-sm sm:p-4" : "px-5 py-4 text-sm sm:px-5")}> <div className={classNames(app.isInstalled ? "p-4 text-sm sm:p-4" : "px-5 py-4 text-sm sm:px-5")}>
<div className="flex w-full flex-col gap-2 sm:flex-row sm:gap-0"> <div className="flex w-full flex-col gap-2 sm:flex-row sm:gap-0">
{/* Don't know why but w-[42px] isn't working, started happening when I started using next/dynamic */} {/* Don't know why but w-[42px] isn't working, started happening when I started using next/dynamic */}
<Link href={"/apps/" + app.slug} className="mr-3 h-auto w-10 rounded-sm"> <Link
href={"/apps/" + app.slug}
className={classNames(app?.isInstalled ? "mr-[11px]" : "mr-3", "h-auto w-10 rounded-sm")}>
<img <img
className={classNames( className={classNames(
app?.logo.includes("-dark") && "dark:invert", app?.logo.includes("-dark") && "dark:invert",
`w-full ${app.isInstalled ? "min-w-[42px]" : "min-w-[32.47px]"}` app?.isInstalled ? "min-w-[42px]" : "min-w-[40px]",
"w-full"
)} )}
src={app?.logo} src={app?.logo}
alt={app?.name} alt={app?.name}
/> />
</Link> </Link>
<div className="flex flex-col"> <div className="flex flex-col pe-3">
<span className="text-emphasis text-base font-semibold leading-4">{app?.name}</span> <div className="text-emphasis">
<p className="text-default max-w-md truncate pt-2 text-sm font-normal ltr:pr-2 rtl:pl-2"> <span className={classNames(app?.isInstalled && "text-base", "font-semibold leading-4")}>
{app?.name}
</span>
{!app?.isInstalled && (
<span className="bg-emphasis ml-1 rounded px-1 py-0.5 text-xs font-medium leading-3 tracking-[0.01em]">
{app?.categories[0].charAt(0).toUpperCase() + app?.categories[0].slice(1)}
</span>
)}
</div>
<p title={app?.description} className="text-default line-clamp-1 pt-1 text-sm font-normal">
{description || app?.description} {description || app?.description}
</p> </p>
</div> </div>
@@ -105,7 +116,9 @@ export default function AppCard({
</div> </div>
<div ref={animationRef}> <div ref={animationRef}>
{app?.isInstalled && switchChecked && <hr className="border-subtle" />} {app?.isInstalled && switchChecked && <hr className="border-subtle" />}
{app?.isInstalled && switchChecked ? <div className="p-4 text-sm sm:px-4">{children}</div> : null} {app?.isInstalled && switchChecked ? (
<div className="p-4 pt-5 text-sm [&_input]:mb-0 [&_input]:leading-4">{children}</div>
) : null}
</div> </div>
</div> </div>
); );
@@ -33,15 +33,10 @@ const AppCategoryNavigation = ({
return ( return (
<div className={cs("flex flex-col gap-x-6 md:p-0 xl:flex-row", classNames?.root ?? className)}> <div className={cs("flex flex-col gap-x-6 md:p-0 xl:flex-row", classNames?.root ?? className)}>
<div className="hidden xl:block"> <div className="hidden xl:block">
<VerticalTabs <VerticalTabs tabs={appCategories} sticky linkShallow itemClassname={classNames?.verticalTabsItem} />
tabs={appCategories}
sticky
linkProps={{ shallow: true }}
itemClassname={classNames?.verticalTabsItem}
/>
</div> </div>
<div className="block overflow-x-scroll xl:hidden"> <div className="block overflow-x-scroll xl:hidden">
<HorizontalTabs tabs={appCategories} linkProps={{ shallow: true }} /> <HorizontalTabs tabs={appCategories} linkShallow />
</div> </div>
<main className={classNames?.container ?? containerClassname} ref={animationRef}> <main className={classNames?.container ?? containerClassname} ref={animationRef}>
{children} {children}
@@ -76,7 +76,7 @@ export default function OmniInstallAppButton({
className="[@media(max-width:260px)]:w-full [@media(max-width:260px)]:justify-center" className="[@media(max-width:260px)]:w-full [@media(max-width:260px)]:justify-center"
StartIcon={Plus} StartIcon={Plus}
{...props}> {...props}>
{t("install")} {t("add")}
</Button> </Button>
); );
}} }}
+2 -2
View File
@@ -1,7 +1,7 @@
import { google } from "googleapis"; import { google } from "googleapis";
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import { WEBAPP_URL } from "@calcom/lib/constants"; import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants";
import { encodeOAuthState } from "../../_utils/encodeOAuthState"; import { encodeOAuthState } from "../../_utils/encodeOAuthState";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
@@ -22,7 +22,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret;
if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); if (!client_id) return res.status(400).json({ message: "Google client_id missing." });
if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." });
const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; const redirect_uri = WEBAPP_URL_FOR_OAUTH + "/api/integrations/googlecalendar/callback";
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);
const authUrl = oAuth2Client.generateAuthUrl({ const authUrl = oAuth2Client.generateAuthUrl({
@@ -1,7 +1,7 @@
import { google } from "googleapis"; import { google } from "googleapis";
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import { WEBAPP_URL, CAL_URL } from "@calcom/lib/constants"; import { WEBAPP_URL_FOR_OAUTH, CAL_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
@@ -30,7 +30,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); if (!client_id) return res.status(400).json({ message: "Google client_id missing." });
if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." });
const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; const redirect_uri = WEBAPP_URL_FOR_OAUTH + "/api/integrations/googlecalendar/callback";
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri);
@@ -23,6 +23,27 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
}} }}
switchChecked={enabled} switchChecked={enabled}
teamId={eventType.team?.id || undefined}> teamId={eventType.team?.id || undefined}>
<div className="flex flex-col gap-2">
<TextField
name="Plausible URL"
defaultValue="https://plausible.io/js/script.js"
placeholder="https://plausible.io/js/script.js"
value={plausibleUrl}
disabled={disabled}
onChange={(e) => {
setAppData("PLAUSIBLE_URL", e.target.value);
}}
/>
<TextField
disabled={disabled}
name="Tracked Domain"
placeholder="yourdomain.com"
value={trackingId}
onChange={(e) => {
setAppData("trackingId", e.target.value);
}}
/>
</div>
<TextField <TextField
name="Plausible URL" name="Plausible URL"
defaultValue="https://plausible.io/js/script.js" defaultValue="https://plausible.io/js/script.js"
@@ -46,7 +46,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
}} }}
switchChecked={enabled} switchChecked={enabled}
teamId={eventType.team?.id || undefined}> teamId={eventType.team?.id || undefined}>
<div className="flex w-full flex-col gap-2 text-sm"> <div className="flex w-full flex-col gap-5 text-sm">
<div className="flex w-full"> <div className="flex w-full">
<TextField <TextField
name="hello" name="hello"
@@ -145,7 +145,7 @@ function NewFormDialog({ appUrl }: { appUrl: string }) {
/> />
)} )}
</div> </div>
<DialogFooter showDivider className="mt-12 flex flex-row-reverse gap-x-2"> <DialogFooter showDivider className="mt-12">
<DialogClose /> <DialogClose />
<Button loading={mutation.isLoading} data-testid="add-form" type="submit"> <Button loading={mutation.isLoading} data-testid="add-form" type="submit">
{t("continue")} {t("continue")}
+1
View File
@@ -12,6 +12,7 @@ items:
Skiff is a privacy-first, end-to-end encrypted workspace with Mail, Pages, Drive, and Calendar applications. Skiff Calendar integrates with Cal.com, enabling you to schedule appointments, organize events, and use your preferred video conferencing product. Skiff is a privacy-first, end-to-end encrypted workspace with Mail, Pages, Drive, and Calendar applications. Skiff Calendar integrates with Cal.com, enabling you to schedule appointments, organize events, and use your preferred video conferencing product.
## Features ## Features
- **Full workspace** — beyond email and calendar, Skiff enables writing and collaborating on end-to-end encrypted notes or wikis. You can also upload, preview, and share files. - **Full workspace** — beyond email and calendar, Skiff enables writing and collaborating on end-to-end encrypted notes or wikis. You can also upload, preview, and share files.
- **Native applications** — Skiff has native macOS, Windows, iOS, and Android applications, ensuring you can stay on top of your schedule from any device. - **Native applications** — Skiff has native macOS, Windows, iOS, and Android applications, ensuring you can stay on top of your schedule from any device.
- **Multiple accounts** — all Skiff products support multiple accounts, or sharing your entire team to collaborate inside one workspace. - **Multiple accounts** — all Skiff products support multiple accounts, or sharing your entire team to collaborate inside one workspace.
+17 -1
View File
@@ -5,6 +5,7 @@ import type { z } from "zod";
import { getCalendar } from "@calcom/app-store/_utils/getCalendar"; import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
import { FAKE_DAILY_CREDENTIAL } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter"; import { FAKE_DAILY_CREDENTIAL } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter";
import { appKeysSchema as calVideoKeysSchema } from "@calcom/app-store/dailyvideo/zod";
import { getEventLocationTypeFromApp } from "@calcom/app-store/locations"; import { getEventLocationTypeFromApp } from "@calcom/app-store/locations";
import { MeetLocationType } from "@calcom/app-store/locations"; import { MeetLocationType } from "@calcom/app-store/locations";
import getApps from "@calcom/app-store/utils"; import getApps from "@calcom/app-store/utils";
@@ -94,7 +95,22 @@ export default class EventManager {
public async create(event: CalendarEvent): Promise<CreateUpdateResult> { public async create(event: CalendarEvent): Promise<CreateUpdateResult> {
const evt = processLocation(event); const evt = processLocation(event);
// Fallback to cal video if no location is set // Fallback to cal video if no location is set
if (!evt.location) evt["location"] = "integrations:daily"; if (!evt.location) {
// See if cal video is enabled & has keys
const calVideo = await prisma.app.findFirst({
where: {
slug: "daily-video",
},
select: {
keys: true,
enabled: true,
},
});
const calVideoKeys = calVideoKeysSchema.safeParse(calVideo?.keys);
if (calVideo?.enabled && calVideoKeys.success) evt["location"] = "integrations:daily";
}
// Fallback to Cal Video if Google Meet is selected w/o a Google Cal // Fallback to Cal Video if Google Meet is selected w/o a Google Cal
if (evt.location === MeetLocationType && evt.destinationCalendar?.integration !== "google_calendar") { if (evt.location === MeetLocationType && evt.destinationCalendar?.integration !== "google_calendar") {
+2 -1
View File
@@ -7,6 +7,7 @@ export type EventNameObjectType = {
attendeeName: string; attendeeName: string;
eventType: string; eventType: string;
eventName?: string | null; eventName?: string | null;
teamName?: string | null;
host: string; host: string;
location?: string; location?: string;
bookingFields?: Prisma.JsonObject; bookingFields?: Prisma.JsonObject;
@@ -17,7 +18,7 @@ export function getEventName(eventNameObj: EventNameObjectType, forAttendeeView
if (!eventNameObj.eventName) if (!eventNameObj.eventName)
return eventNameObj.t("event_between_users", { return eventNameObj.t("event_between_users", {
eventName: eventNameObj.eventType, eventName: eventNameObj.eventType,
host: eventNameObj.host, host: eventNameObj.teamName || eventNameObj.host,
attendeeName: eventNameObj.attendeeName, attendeeName: eventNameObj.attendeeName,
interpolation: { interpolation: {
escapeValue: false, escapeValue: false,
@@ -70,16 +70,7 @@ export default class OrganizerScheduledEmail extends BaseEmail {
protected getNodeMailerPayload(): Record<string, unknown> { protected getNodeMailerPayload(): Record<string, unknown> {
const clonedCalEvent = cloneDeep(this.calEvent); const clonedCalEvent = cloneDeep(this.calEvent);
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
const toAddresses = [this.calEvent.organizer.email];
if (this.calEvent.team) {
this.calEvent.team.members.forEach((member) => {
const memberAttendee = this.calEvent.attendees.find((attendee) => attendee.email === member.email);
if (memberAttendee) {
toAddresses.push(memberAttendee.email);
}
});
}
return { return {
icalEvent: { icalEvent: {
+3
View File
@@ -82,10 +82,13 @@
</style> </style>
</head> </head>
<body> <body>
<span style="display: block"><a href="?color-scheme=dark">With Dark Color Scheme for the Page</a></span>
<span style="display: block"><a href="?nonResponsive">Non responsive version of this page here</a></span> <span style="display: block"><a href="?nonResponsive">Non responsive version of this page here</a></span>
<span style="display: block" <span style="display: block"
><a href="?only=prerender-test">Go to Pre-render test page only</a><small></small ><a href="?only=prerender-test">Go to Pre-render test page only</a><small></small
></span> ></span>
<button onclick="document.documentElement.style.colorScheme='dark'">Toggle Dark Scheme</button>
<button onclick="document.documentElement.style.colorScheme='light'">Toggle Light Scheme</button>
<div> <div>
<script> <script>
if (only === "all" || only === "prerender-test") { if (only === "all" || only === "prerender-test") {
+20
View File
@@ -6,8 +6,28 @@ const callback = function (e) {
console.log("Event: ", e.type, detail); console.log("Event: ", e.type, detail);
}; };
document.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
if ("href" in target && typeof target.href === "string") {
const toUrl = new URL(target.href);
const pageUrl = new URL(document.URL);
for (const [name, value] of pageUrl.searchParams.entries()) {
if (toUrl.searchParams.get(name) === null) {
toUrl.searchParams.append(decodeURIComponent(name), value);
}
}
location.href = `?${toUrl.searchParams.toString()}#${toUrl.hash}`;
e.preventDefault();
}
});
const searchParams = new URL(document.URL).searchParams; const searchParams = new URL(document.URL).searchParams;
const only = searchParams.get("only"); const only = searchParams.get("only");
const colorScheme = searchParams.get("color-scheme");
if (colorScheme) {
document.documentElement.style.colorScheme = colorScheme;
}
const themeInParam = searchParams.get("theme"); const themeInParam = searchParams.get("theme");
const validThemes = ["light", "dark", "auto"] as const; const validThemes = ["light", "dark", "auto"] as const;
const theme = validThemes.includes((themeInParam as (typeof validThemes)[number]) || "") const theme = validThemes.includes((themeInParam as (typeof validThemes)[number]) || "")
+15 -1
View File
@@ -18,6 +18,7 @@ export type UiConfig = {
//TODO: Extract from tailwind the list of all custom variables and support them in auto-completion as well as runtime validation. Followup with listing all variables in Embed Snippet Generator UI. //TODO: Extract from tailwind the list of all custom variables and support them in auto-completion as well as runtime validation. Followup with listing all variables in Embed Snippet Generator UI.
cssVarsPerTheme?: Record<Theme, Record<string, string>>; cssVarsPerTheme?: Record<Theme, Record<string, string>>;
layout?: BookerLayouts; layout?: BookerLayouts;
colorScheme?: string | null;
}; };
type SetStyles = React.Dispatch<React.SetStateAction<EmbedStyles>>; type SetStyles = React.Dispatch<React.SetStateAction<EmbedStyles>>;
@@ -336,6 +337,10 @@ const methods = {
window.CalEmbed.applyCssVars(uiConfig.cssVarsPerTheme); window.CalEmbed.applyCssVars(uiConfig.cssVarsPerTheme);
} }
if (uiConfig.colorScheme) {
actOnColorScheme(uiConfig.colorScheme);
}
if (embedStore.setUiConfig) { if (embedStore.setUiConfig) {
runAllUiSetters(uiConfig); runAllUiSetters(uiConfig);
} }
@@ -461,10 +466,12 @@ if (isBrowser) {
embedStore.uiConfig = { embedStore.uiConfig = {
// TODO: Add theme as well here // TODO: Add theme as well here
// theme: colorScheme: url.searchParams.get("ui.color-scheme"),
layout: url.searchParams.get("layout") as BookerLayouts, layout: url.searchParams.get("layout") as BookerLayouts,
}; };
actOnColorScheme(embedStore.uiConfig.colorScheme);
if (url.searchParams.get("prerender") !== "true" && window?.isEmbed?.()) { if (url.searchParams.get("prerender") !== "true" && window?.isEmbed?.()) {
log("Initializing embed-iframe"); log("Initializing embed-iframe");
// HACK // HACK
@@ -523,3 +530,10 @@ function runAllUiSetters(uiConfig: UiConfig) {
embedStore.uiConfig = uiConfig; embedStore.uiConfig = uiConfig;
embedStore.setUiConfig.forEach((setUiConfig) => setUiConfig(uiConfig)); embedStore.setUiConfig.forEach((setUiConfig) => setUiConfig(uiConfig));
} }
function actOnColorScheme(colorScheme: string | null | undefined) {
if (!colorScheme) {
return;
}
document.documentElement.style.colorScheme = colorScheme;
}
+101 -14
View File
@@ -116,6 +116,31 @@ function validate(data: Record<string, unknown>, schema: ValidationSchema) {
} }
} }
function getColorScheme(el: Element) {
const pageColorScheme = getComputedStyle(el).colorScheme;
if (pageColorScheme === "dark" || pageColorScheme === "light") {
return pageColorScheme;
}
return null;
}
function withColorScheme(
queryObject: PrefillAndIframeAttrsConfig & { guest?: string | string[] },
containerEl: Element
) {
// If color-scheme not explicitly configured, keep it same as the webpage that has the iframe
// This is done to avoid having an opaque background of iframe that arises when they aren't same. We really need to have a transparent background to make embed part of the page
// https://fvsch.com/transparent-iframes#:~:text=the%20resolution%20was%3A-,If%20the%20color%20scheme%20of%20an%20iframe%20differs%20from%20embedding%20document%2C%20iframe%20gets%20an%20opaque%20canvas%20background%20appropriate%20to%20its%20color%20scheme.,-So%20the%20dark
if (!queryObject["ui.color-scheme"]) {
const colorScheme = getColorScheme(containerEl);
// Only handle two color-schemes for now. We don't want to have unintented affect by always explicitly adding color-scheme
if (colorScheme) {
queryObject["ui.color-scheme"] = colorScheme;
}
}
return queryObject;
}
type SingleInstructionMap = { type SingleInstructionMap = {
// TODO: This makes api("on", {}) loose it's generic type. Find a way to fix it. // TODO: This makes api("on", {}) loose it's generic type. Find a way to fix it.
// e.g. api("on", { action: "__dimensionChanged", callback: (e) => { /* `e.detail.data` has all possible values for all events/actions */} }); // e.g. api("on", { action: "__dimensionChanged", callback: (e) => { /* `e.detail.data` has all possible values for all events/actions */} });
@@ -139,8 +164,8 @@ export type PrefillAndIframeAttrsConfig = Record<string, string | string[] | Rec
// TODO: It should have a dedicated prefill prop // TODO: It should have a dedicated prefill prop
// prefill: {}, // prefill: {},
// TODO: Move layout and theme as nested props of ui as it makes it clear that these two can be configured using `ui` instruction as well any time. // TODO: Rename layout and theme as ui.layout and ui.theme as it makes it clear that these two can be configured using `ui` instruction as well any time.
// ui: {layout; theme} "ui.color-scheme"?: string;
layout?: `${BookerLayouts}`; layout?: `${BookerLayouts}`;
theme?: EmbedThemeConfig; theme?: EmbedThemeConfig;
}; };
@@ -217,6 +242,9 @@ export class Cal {
}; };
} }
/**
* Iframe is added invisible and shown only after color-scheme is set by the embedded calLink to avoid flash of non-transparent(white/black) background
*/
createIframe({ createIframe({
calLink, calLink,
queryObject = {}, queryObject = {},
@@ -255,9 +283,14 @@ export class Cal {
urlInstance.pathname = `${urlInstance.pathname}/embed`; urlInstance.pathname = `${urlInstance.pathname}/embed`;
} }
urlInstance.searchParams.set("embed", this.namespace); urlInstance.searchParams.set("embed", this.namespace);
if (config.debug) { if (config.debug) {
urlInstance.searchParams.set("debug", "" + config.debug); urlInstance.searchParams.set("debug", "" + config.debug);
} }
// Keep iframe invisible, till the embedded calLink sets its color-scheme. This is so that there is no flash of non-transparent(white/black) background
iframe.style.visibility = "hidden";
if (config.uiDebug) { if (config.uiDebug) {
iframe.style.border = "1px solid green"; iframe.style.border = "1px solid green";
} }
@@ -334,6 +367,13 @@ export class Cal {
this.actionManager.on("__iframeReady", () => { this.actionManager.on("__iframeReady", () => {
this.iframeReady = true; this.iframeReady = true;
if (this.iframe) {
// It's a bit late to make the iframe visible here. We just needed to wait for the HTML tag of the embedded calLink to be rendered(which then informs the browser of the color-scheme)
// Right now it would wait for embed-iframe.js bundle to be loaded as well. We can speed that up by inlining the JS that informs about color-scheme being set in the HTML.
// But it's okay to do it here for now because the embedded calLink also keeps itself hidden till it receives `parentKnowsIframeReady` message(It has it's own reasons for that)
// Once the embedded calLink starts not hiding the document, we should optimize this line to make the iframe visible earlier than this.
this.iframe.style.visibility = "visible";
}
this.doInIframe({ method: "parentKnowsIframeReady" } as const); this.doInIframe({ method: "parentKnowsIframeReady" } as const);
this.iframeDoQueue.forEach((doInIframeArg) => { this.iframeDoQueue.forEach((doInIframeArg) => {
this.doInIframe(doInIframeArg); this.doInIframe(doInIframeArg);
@@ -369,7 +409,7 @@ export class Cal {
class CalApi { class CalApi {
cal: Cal; cal: Cal;
static initializedNamespaces = [] as string[];
constructor(cal: Cal) { constructor(cal: Cal) {
this.cal = cal; this.cal = cal;
} }
@@ -379,6 +419,8 @@ class CalApi {
config = (namespaceOrConfig || {}) as Config; config = (namespaceOrConfig || {}) as Config;
} }
CalApi.initializedNamespaces.push(this.cal.namespace);
const { calOrigin: calOrigin, origin: origin, ...restConfig } = config; const { calOrigin: calOrigin, origin: origin, ...restConfig } = config;
this.cal.__config.calOrigin = calOrigin || origin || this.cal.__config.calOrigin; this.cal.__config.calOrigin = calOrigin || origin || this.cal.__config.calOrigin;
@@ -421,23 +463,31 @@ class CalApi {
if (typeof config.iframeAttrs === "string" || config.iframeAttrs instanceof Array) { if (typeof config.iframeAttrs === "string" || config.iframeAttrs instanceof Array) {
throw new Error("iframeAttrs should be an object"); throw new Error("iframeAttrs should be an object");
} }
config.embedType = "inline"; const containerEl =
const iframe = this.cal.createIframe({ calLink, queryObject: Cal.getQueryObject(config) });
iframe.style.height = "100%";
iframe.style.width = "100%";
const element =
elementOrSelector instanceof HTMLElement elementOrSelector instanceof HTMLElement
? elementOrSelector ? elementOrSelector
: document.querySelector(elementOrSelector); : document.querySelector(elementOrSelector);
if (!element) {
if (!containerEl) {
throw new Error("Element not found"); throw new Error("Element not found");
} }
element.classList.add("cal-inline-container");
config.embedType = "inline";
const iframe = this.cal.createIframe({
calLink,
queryObject: withColorScheme(Cal.getQueryObject(config), containerEl),
});
iframe.style.height = "100%";
iframe.style.width = "100%";
containerEl.classList.add("cal-inline-container");
const template = document.createElement("template"); const template = document.createElement("template");
template.innerHTML = `<cal-inline style="max-height:inherit;height:inherit;min-height:inherit;display:flex;position:relative;flex-wrap:wrap;width:100%"></cal-inline><style>.cal-inline-container::-webkit-scrollbar{display:none}.cal-inline-container{scrollbar-width:none}</style>`; template.innerHTML = `<cal-inline style="max-height:inherit;height:inherit;min-height:inherit;display:flex;position:relative;flex-wrap:wrap;width:100%"></cal-inline><style>.cal-inline-container::-webkit-scrollbar{display:none}.cal-inline-container{scrollbar-width:none}</style>`;
this.cal.inlineEl = template.content.children[0]; this.cal.inlineEl = template.content.children[0];
this.cal.inlineEl.appendChild(iframe); this.cal.inlineEl.appendChild(iframe);
element.appendChild(template.content); containerEl.appendChild(template.content);
} }
floatingButton({ floatingButton({
@@ -523,8 +573,14 @@ class CalApi {
if (typeof config.iframeAttrs === "string" || config.iframeAttrs instanceof Array) { if (typeof config.iframeAttrs === "string" || config.iframeAttrs instanceof Array) {
throw new Error("iframeAttrs should be an object"); throw new Error("iframeAttrs should be an object");
} }
config.embedType = "modal"; config.embedType = "modal";
const iframe = this.cal.createIframe({ calLink, calOrigin, queryObject: Cal.getQueryObject(config) }); const containerEl = document.body;
const iframe = this.cal.createIframe({
calLink,
queryObject: withColorScheme(Cal.getQueryObject(config), containerEl),
});
iframe.style.borderRadius = "8px"; iframe.style.borderRadius = "8px";
iframe.style.height = "100%"; iframe.style.height = "100%";
@@ -537,7 +593,7 @@ class CalApi {
this.cal.actionManager.on("__closeIframe", () => { this.cal.actionManager.on("__closeIframe", () => {
this.cal.modalBox.setAttribute("state", "closed"); this.cal.modalBox.setAttribute("state", "closed");
}); });
document.body.appendChild(template.content); containerEl.appendChild(template.content);
} }
on<T extends keyof EventDataMap>({ on<T extends keyof EventDataMap>({
@@ -646,7 +702,9 @@ export interface CalWindow extends Window {
Cal: GlobalCal; Cal: GlobalCal;
} }
globalCal.instance = new Cal("", globalCal.q); const DEFAULT_NAMESPACE = "";
globalCal.instance = new Cal(DEFAULT_NAMESPACE, globalCal.q);
for (const [ns, api] of Object.entries(globalCal.ns)) { for (const [ns, api] of Object.entries(globalCal.ns)) {
api.instance = new Cal(ns, api.q); api.instance = new Cal(ns, api.q);
} }
@@ -711,3 +769,32 @@ document.addEventListener("click", (e) => {
calOrigin, calOrigin,
}); });
}); });
let currentColorScheme: string | null = null;
(function watchAndActOnColorSchemeChange() {
// TODO: Maybe find a better way to identify change in color-scheme, a mutation observer seems overkill for this. Settle with setInterval for now.
setInterval(() => {
const colorScheme = getColorScheme(document.body);
if (colorScheme && colorScheme !== currentColorScheme) {
currentColorScheme = colorScheme;
// Go through all the embeds on the same page and update all of them with this info
CalApi.initializedNamespaces.forEach((ns) => {
const api = getEmbedApiFn(ns);
api("ui", {
colorScheme: colorScheme,
});
});
}
}, 50);
})();
function getEmbedApiFn(ns: string) {
let api;
if (ns === DEFAULT_NAMESPACE) {
api = globalCal;
} else {
api = globalCal.ns[ns];
}
return api;
}
@@ -5,14 +5,12 @@ import { trpc } from "@calcom/trpc/react";
import type { ButtonProps } from "@calcom/ui"; import type { ButtonProps } from "@calcom/ui";
import { import {
Button, Button,
ConfirmationDialogContent,
Dialog, Dialog,
DialogContent,
DialogTrigger, DialogTrigger,
showToast, showToast,
DialogFooter,
DialogClose,
} from "@calcom/ui"; } from "@calcom/ui";
import { Trash, AlertCircle } from "@calcom/ui/components/icon"; import { Trash } from "@calcom/ui/components/icon";
export default function DisconnectIntegration({ export default function DisconnectIntegration({
credentialId, credentialId,
@@ -62,18 +60,15 @@ export default function DisconnectIntegration({
{label && label} {label && label}
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent <ConfirmationDialogContent
variety="danger"
title={t("remove_app")} title={t("remove_app")}
description={t("are_you_sure_you_want_to_remove_this_app")} confirmBtnText={t("yes_remove_app")}
type="confirmation" onConfirm={() => {
Icon={AlertCircle}> mutation.mutate({ id: credentialId });
<DialogFooter> }}>
<DialogClose onClick={() => setModalOpen(false)} /> <p className="mt-5">{t("are_you_sure_you_want_to_remove_this_app")}</p>
<DialogClose color="primary" onClick={() => mutation.mutate({ id: credentialId })}> </ConfirmationDialogContent>
{t("yes_remove_app")}
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog> </Dialog>
</> </>
); );
@@ -115,7 +115,7 @@ const providers: Provider[] = [
throw new Error(ErrorCode.IncorrectEmailPassword); throw new Error(ErrorCode.IncorrectEmailPassword);
} }
if (user.password || !credentials.totpCode) { if (user.password && !credentials.totpCode) {
if (!user.password) { if (!user.password) {
throw new Error(ErrorCode.IncorrectEmailPassword); throw new Error(ErrorCode.IncorrectEmailPassword);
} }
@@ -560,7 +560,7 @@ export const AUTH_OPTIONS: AuthOptions = {
console.error("Error while linking account of already existing user"); console.error("Error while linking account of already existing user");
} }
} }
if (existingUser.twoFactorEnabled) { if (existingUser.twoFactorEnabled && existingUser.identityProvider === idP) {
return loginWithTotp(existingUser); return loginWithTotp(existingUser);
} else { } else {
return true; return true;
@@ -600,7 +600,11 @@ export const AUTH_OPTIONS: AuthOptions = {
if (existingUserWithEmail) { if (existingUserWithEmail) {
// if self-hosted then we can allow auto-merge of identity providers if email is verified // if self-hosted then we can allow auto-merge of identity providers if email is verified
if (!hostedCal && existingUserWithEmail.emailVerified) { if (
!hostedCal &&
existingUserWithEmail.emailVerified &&
existingUserWithEmail.identityProvider !== IdentityProvider.CAL
) {
if (existingUserWithEmail.twoFactorEnabled) { if (existingUserWithEmail.twoFactorEnabled) {
return loginWithTotp(existingUserWithEmail); return loginWithTotp(existingUserWithEmail);
} else { } else {
+3 -3
View File
@@ -23,7 +23,7 @@ import { useBookerStore, useInitializeBookerStore } from "./store";
import type { BookerLayout, BookerProps } from "./types"; import type { BookerLayout, BookerProps } from "./types";
import { useEvent } from "./utils/event"; import { useEvent } from "./utils/event";
import { validateLayout } from "./utils/layout"; import { validateLayout } from "./utils/layout";
import { getQueryParam } from './utils/query-param'; import { getQueryParam } from "./utils/query-param";
import { useBrandColors } from "./utils/use-brand-colors"; import { useBrandColors } from "./utils/use-brand-colors";
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy")); const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy"));
@@ -120,9 +120,9 @@ const BookerComponent = ({
layout !== _layout layout !== _layout
) { ) {
const validLayout = bookerLayouts.enabledLayouts.find((userLayout) => userLayout === layout); const validLayout = bookerLayouts.enabledLayouts.find((userLayout) => userLayout === layout);
validLayout && setLayout(validLayout) validLayout && setLayout(validLayout);
} }
}, [bookerLayouts, validateLayout, setLayout,_layout]); }, [bookerLayouts, validateLayout, setLayout, _layout]);
useEffect(() => { useEffect(() => {
if (event.isLoading) return setBookerState("loading"); if (event.isLoading) return setBookerState("loading");
@@ -1,6 +1,7 @@
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import type { UseMutationResult } from "@tanstack/react-query"; import type { UseMutationResult } from "@tanstack/react-query";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import type { TFunction } from "next-i18next"; import type { TFunction } from "next-i18next";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useMemo, useRef } from "react"; import { useEffect, useMemo, useRef } from "react";
@@ -22,6 +23,7 @@ import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/
import getBookingResponsesSchema, { import getBookingResponsesSchema, {
getBookingResponsesPartialSchema, getBookingResponsesPartialSchema,
} from "@calcom/features/bookings/lib/getBookingResponsesSchema"; } from "@calcom/features/bookings/lib/getBookingResponsesSchema";
import { getFullName } from "@calcom/features/form-builder/utils";
import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect"; import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { MINUTES_TO_BOOK } from "@calcom/lib/constants"; import { MINUTES_TO_BOOK } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -40,6 +42,7 @@ type BookEventFormProps = {
}; };
export const BookEventForm = ({ onCancel }: BookEventFormProps) => { export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
const session = useSession();
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation({ const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation({
trpc: { context: { skipBatch: true } }, trpc: { context: { skipBatch: true } },
}); });
@@ -114,8 +117,12 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
}); });
const defaultUserValues = { const defaultUserValues = {
email: rescheduleUid ? bookingData?.attendees[0].email : parsedQuery["email"] || "", email: rescheduleUid
name: rescheduleUid ? bookingData?.attendees[0].name : parsedQuery["name"] || "", ? bookingData?.attendees[0].email
: parsedQuery["email"] || session.data?.user?.email || "",
name: rescheduleUid
? bookingData?.attendees[0].name
: parsedQuery["name"] || session.data?.user?.name || "",
}; };
if (!isRescheduling) { if (!isRescheduling) {
@@ -193,12 +200,13 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
const createBookingMutation = useMutation(createBooking, { const createBookingMutation = useMutation(createBooking, {
onSuccess: async (responseData) => { onSuccess: async (responseData) => {
const { uid, paymentUid } = responseData; const { uid, paymentUid } = responseData;
const fullName = getFullName(bookingForm.getValues("responses.name"));
if (paymentUid) { if (paymentUid) {
return await router.push( return await router.push(
createPaymentLink({ createPaymentLink({
paymentUid, paymentUid,
date: timeslot, date: timeslot,
name: bookingForm.getValues("responses.name"), name: fullName,
email: bookingForm.getValues("responses.email"), email: bookingForm.getValues("responses.email"),
absolute: false, absolute: false,
}) })
@@ -2,11 +2,11 @@ import { useFormContext } from "react-hook-form";
import type { LocationObject } from "@calcom/app-store/locations"; import type { LocationObject } from "@calcom/app-store/locations";
import getLocationOptionsForSelect from "@calcom/features/bookings/lib/getLocationOptionsForSelect"; import getLocationOptionsForSelect from "@calcom/features/bookings/lib/getLocationOptionsForSelect";
import { FormBuilderField } from "@calcom/features/form-builder"; import { FormBuilderField } from "@calcom/features/form-builder/FormBuilderField";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterOutputs } from "@calcom/trpc/react"; import type { RouterOutputs } from "@calcom/trpc/react";
import { SystemField } from "../../../lib/getBookingFields"; import { SystemField } from "../../../lib/SystemField";
export const BookingFields = ({ export const BookingFields = ({
fields, fields,
@@ -26,6 +26,7 @@ export const BookingFields = ({
return ( return (
// TODO: It might make sense to extract this logic into BookingFields config, that would allow to quickly configure system fields and their editability in fresh booking and reschedule booking view // TODO: It might make sense to extract this logic into BookingFields config, that would allow to quickly configure system fields and their editability in fresh booking and reschedule booking view
// The logic here intends to make modifications to booking fields based on the way we want to specifically show Booking Form
<div> <div>
{fields.map((field, index) => { {fields.map((field, index) => {
// During reschedule by default all system fields are readOnly. Make them editable on case by case basis. // During reschedule by default all system fields are readOnly. Make them editable on case by case basis.
@@ -33,7 +34,6 @@ export const BookingFields = ({
let readOnly = let readOnly =
(field.editable === "system" || field.editable === "system-but-optional") && !!rescheduleUid; (field.editable === "system" || field.editable === "system-but-optional") && !!rescheduleUid;
let noLabel = false;
let hidden = !!field.hidden; let hidden = !!field.hidden;
const fieldViews = field.views; const fieldViews = field.views;
@@ -88,28 +88,10 @@ export const BookingFields = ({
field.options = options.filter( field.options = options.filter(
(location): location is NonNullable<(typeof options)[number]> => !!location (location): location is NonNullable<(typeof options)[number]> => !!location
); );
// If we have only one option and it has an input, we don't show the field label because Option name acts as label.
// e.g. If it's just Attendee Phone Number option then we don't show `Location` label
if (field.options.length === 1) {
if (field.optionsInputs[field.options[0].value]) {
noLabel = true;
} else {
// If there's only one option and it doesn't have an input, we don't show the field at all because it's visible in the left side bar
hidden = true;
}
}
} }
const label = noLabel ? "" : field.label || t(field.defaultLabel || "");
const placeholder = field.placeholder || t(field.defaultPlaceholder || "");
return ( return (
<FormBuilderField <FormBuilderField className="mb-4" field={{ ...field, hidden }} readOnly={readOnly} key={index} />
className="mb-4"
field={{ ...field, label, placeholder, hidden }}
readOnly={readOnly}
key={index}
/>
); );
})} })}
</div> </div>
+1 -1
View File
@@ -128,7 +128,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
if (["week_view", "column_view"].includes(layout) && !get().selectedDate) { if (["week_view", "column_view"].includes(layout) && !get().selectedDate) {
set({ selectedDate: dayjs().format("YYYY-MM-DD") }); set({ selectedDate: dayjs().format("YYYY-MM-DD") });
} }
updateQueryParam("layout", layout) updateQueryParam("layout", layout);
return set({ layout }); return set({ layout });
}, },
selectedDate: getQueryParam("date") || null, selectedDate: getQueryParam("date") || null,
@@ -5,7 +5,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterOutputs } from "@calcom/trpc/react"; import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import { AnimatedPopover } from "@calcom/ui"; import { AnimatedPopover } from "@calcom/ui";
import { Checkbox } from "@calcom/ui"; import { CheckboxField } from "@calcom/ui";
import { groupBy } from "../groupBy"; import { groupBy } from "../groupBy";
import { useFilterQuery } from "../lib/useFilterQuery"; import { useFilterQuery } from "../lib/useFilterQuery";
@@ -73,7 +73,7 @@ export const EventTypeFilter = () => {
</div> </div>
{groupedEventTypes[teamName].map((eventType) => ( {groupedEventTypes[teamName].map((eventType) => (
<div key={eventType.id} className="flex items-center px-4 py-1.5"> <div key={eventType.id} className="flex items-center px-4 py-1.5">
<Checkbox <CheckboxField
checked={query.eventTypeIds?.includes(eventType.id)} checked={query.eventTypeIds?.includes(eventType.id)}
onChange={(e) => { onChange={(e) => {
if (e.target.checked) { if (e.target.checked) {
@@ -27,7 +27,7 @@ export const EventDuration = ({ event }: { event: PublicEvent }) => {
{event.metadata.multipleDuration.map((duration) => ( {event.metadata.multipleDuration.map((duration) => (
<Badge <Badge
variant="gray" variant="gray"
className={classNames(selectedDuration === duration && "bg-inverted text-inverted")} className={classNames(selectedDuration === duration && "bg-brand-default text-brand")}
size="md" size="md"
key={duration} key={duration}
onClick={() => setSelectedDuration(duration)}>{`${duration} ${t("minute_timeUnit")}`}</Badge> onClick={() => setSelectedDuration(duration)}>{`${duration} ${t("minute_timeUnit")}`}</Badge>
@@ -1,8 +1,8 @@
import { getEventLocationType, getTranslatedLocation } from "@calcom/app-store/locations"; import { getEventLocationType, getTranslatedLocation } from "@calcom/app-store/locations";
import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Tooltip } from "@calcom/ui"; import { Tooltip } from "@calcom/ui";
import { MapPin } from "@calcom/ui/components/icon"; import { MapPin } from "@calcom/ui/components/icon";
import { classNames } from "@calcom/lib";
import type { PublicEvent } from "../../types"; import type { PublicEvent } from "../../types";
import { EventMetaBlock } from "./Details"; import { EventMetaBlock } from "./Details";
@@ -20,7 +20,7 @@ export const EventLocations = ({ event }: { event: PublicEvent }) => {
return translatedLocation; return translatedLocation;
}; };
const eventLocationType = getEventLocationType(locations[0].type); const eventLocationType = getEventLocationType(locations[0].type);
const icon = (locations.length > 1 || !eventLocationType?.iconUrl) ? MapPin : eventLocationType.iconUrl; const icon = locations.length > 1 || !eventLocationType?.iconUrl ? MapPin : eventLocationType.iconUrl;
return ( return (
<EventMetaBlock icon={icon} isDark={eventLocationType?.iconUrl?.includes("-dark")}> <EventMetaBlock icon={icon} isDark={eventLocationType?.iconUrl?.includes("-dark")}>
@@ -44,13 +44,15 @@ export const EventLocations = ({ event }: { event: PublicEvent }) => {
<li key={`${location.type}-${index}`} className="mt-1"> <li key={`${location.type}-${index}`} className="mt-1">
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<img <img
src={getEventLocationType(location.type)?.iconUrl} src={getEventLocationType(location.type)?.iconUrl}
className={classNames( className={classNames(
"h-3 w-3 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 ", "h-3 w-3 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 ",
!getEventLocationType(location.type)?.iconUrl?.startsWith("/app-store") ? "dark:invert-[.65]" : "" !getEventLocationType(location.type)?.iconUrl?.startsWith("/app-store")
)} ? "dark:invert-[.65]"
alt={`${getEventLocationType(location.type)?.label} icon`} : ""
/> )}
alt={`${getEventLocationType(location.type)?.label} icon`}
/>
<span>{getLocationToDisplay(location)}</span> <span>{getLocationToDisplay(location)}</span>
</div> </div>
</li> </li>
@@ -0,0 +1,11 @@
import { z } from "zod";
export const SystemField = z.enum([
"name",
"email",
"location",
"notes",
"guests",
"rescheduleReason",
"smsReminderNumber",
]);
@@ -1,15 +1,21 @@
import type { EventTypeCustomInput, EventType, Prisma, Workflow } from "@prisma/client"; import type { EventTypeCustomInput, EventType, Prisma, Workflow } from "@prisma/client";
import { z } from "zod"; import type { z } from "zod";
import slugify from "@calcom/lib/slugify"; import slugify from "@calcom/lib/slugify";
import { EventTypeCustomInputType } from "@calcom/prisma/enums"; import { EventTypeCustomInputType } from "@calcom/prisma/enums";
import { import {
BookingFieldType, BookingFieldTypeEnum,
customInputSchema, customInputSchema,
eventTypeBookingFields, eventTypeBookingFields,
EventTypeMetaDataSchema, EventTypeMetaDataSchema,
} from "@calcom/prisma/zod-utils"; } from "@calcom/prisma/zod-utils";
type Fields = z.infer<typeof eventTypeBookingFields>;
if (typeof window !== "undefined") {
console.warn("This file should not be imported on the client side");
}
export const SMS_REMINDER_NUMBER_FIELD = "smsReminderNumber"; export const SMS_REMINDER_NUMBER_FIELD = "smsReminderNumber";
/** /**
@@ -42,18 +48,6 @@ export const getSmsReminderNumberSource = ({
editUrl: `/workflows/${workflowId}`, editUrl: `/workflows/${workflowId}`,
}); });
type Fields = z.infer<typeof eventTypeBookingFields>;
export const SystemField = z.enum([
"name",
"email",
"location",
"notes",
"guests",
"rescheduleReason",
"smsReminderNumber",
]);
/** /**
* This fn is the key to ensure on the fly mapping of customInputs to bookingFields and ensuring that all the systems fields are present and correctly ordered in bookingFields * This fn is the key to ensure on the fly mapping of customInputs to bookingFields and ensuring that all the systems fields are present and correctly ordered in bookingFields
*/ */
@@ -125,12 +119,12 @@ export const ensureBookingInputsHaveSystemFields = ({
// If bookingFields is set already, the migration is done. // If bookingFields is set already, the migration is done.
const handleMigration = !bookingFields.length; const handleMigration = !bookingFields.length;
const CustomInputTypeToFieldType = { const CustomInputTypeToFieldType = {
[EventTypeCustomInputType.TEXT]: BookingFieldType.text, [EventTypeCustomInputType.TEXT]: BookingFieldTypeEnum.text,
[EventTypeCustomInputType.TEXTLONG]: BookingFieldType.textarea, [EventTypeCustomInputType.TEXTLONG]: BookingFieldTypeEnum.textarea,
[EventTypeCustomInputType.NUMBER]: BookingFieldType.number, [EventTypeCustomInputType.NUMBER]: BookingFieldTypeEnum.number,
[EventTypeCustomInputType.BOOL]: BookingFieldType.boolean, [EventTypeCustomInputType.BOOL]: BookingFieldTypeEnum.boolean,
[EventTypeCustomInputType.RADIO]: BookingFieldType.radio, [EventTypeCustomInputType.RADIO]: BookingFieldTypeEnum.radio,
[EventTypeCustomInputType.PHONE]: BookingFieldType.phone, [EventTypeCustomInputType.PHONE]: BookingFieldTypeEnum.phone,
}; };
const smsNumberSources = [] as NonNullable<(typeof bookingFields)[number]["sources"]>; const smsNumberSources = [] as NonNullable<(typeof bookingFields)[number]["sources"]>;
@@ -151,10 +145,12 @@ export const ensureBookingInputsHaveSystemFields = ({
// These fields should be added before other user fields // These fields should be added before other user fields
const systemBeforeFields: typeof bookingFields = [ const systemBeforeFields: typeof bookingFields = [
{ {
defaultLabel: "your_name",
type: "name", type: "name",
// This is the `name` of the main field
name: "name", name: "name",
editable: "system", editable: "system",
// This Label is used in Email only as of now.
defaultLabel: "your_name",
required: true, required: true,
sources: [ sources: [
{ {
@@ -332,7 +328,6 @@ export const ensureBookingInputsHaveSystemFields = ({
}; };
} }
} }
bookingFields = bookingFields.concat(missingSystemAfterFields); bookingFields = bookingFields.concat(missingSystemAfterFields);
return eventTypeBookingFields.brand<"HAS_SYSTEM_FIELDS">().parse(bookingFields); return eventTypeBookingFields.brand<"HAS_SYSTEM_FIELDS">().parse(bookingFields);
@@ -1,7 +1,8 @@
import { isValidPhoneNumber } from "libphonenumber-js"; import { isValidPhoneNumber } from "libphonenumber-js";
import z from "zod"; import z from "zod";
import type { ALL_VIEWS } from "@calcom/features/form-builder/FormBuilderFieldsSchema"; import type { ALL_VIEWS } from "@calcom/features/form-builder/schema";
import { fieldTypesSchemaMap, dbReadResponseSchema } from "@calcom/features/form-builder/schema";
import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import { bookingResponses, emailSchemaRefinement } from "@calcom/prisma/zod-utils"; import { bookingResponses, emailSchemaRefinement } from "@calcom/prisma/zod-utils";
@@ -9,19 +10,8 @@ type EventType = Parameters<typeof preprocess>[0]["eventType"];
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
type View = ALL_VIEWS | (string & {}); type View = ALL_VIEWS | (string & {});
export const bookingResponse = z.union([ export const bookingResponse = dbReadResponseSchema;
z.string(), export const bookingResponsesDbSchema = z.record(dbReadResponseSchema);
z.boolean(),
z.string().array(),
z.object({
optionValue: z.string(),
value: z.string(),
}),
// For variantsConfig case
z.record(z.string()),
]);
export const bookingResponsesDbSchema = z.record(bookingResponse);
const catchAllSchema = bookingResponsesDbSchema; const catchAllSchema = bookingResponsesDbSchema;
@@ -82,6 +72,16 @@ function preprocess<T extends z.ZodType>({
// If the field is not applicable in the current view, then we don't need to do any processing // If the field is not applicable in the current view, then we don't need to do any processing
return; return;
} }
const fieldTypeSchema = fieldTypesSchemaMap[field.type as keyof typeof fieldTypesSchemaMap];
// TODO: Move all the schemas along with their respective types to fieldTypeSchema, that would make schemas shared across Routing Forms builder and Booking Question Formm builder
if (fieldTypeSchema) {
newResponses[field.name] = fieldTypeSchema.preprocess({
response: value,
isPartialSchema,
field,
});
return newResponses;
}
if (field.type === "boolean") { if (field.type === "boolean") {
// Turn a boolean in string to a real boolean // Turn a boolean in string to a real boolean
newResponses[field.name] = value === "true" || value === true; newResponses[field.name] = value === "true" || value === true;
@@ -149,6 +149,19 @@ function preprocess<T extends z.ZodType>({
return; return;
} }
const fieldTypeSchema = fieldTypesSchemaMap[bookingField.type as keyof typeof fieldTypesSchemaMap];
if (fieldTypeSchema) {
fieldTypeSchema.superRefine({
response: value,
ctx,
m,
field: bookingField,
isPartialSchema,
});
return;
}
if (bookingField.type === "multiemail") { if (bookingField.type === "multiemail") {
const emailsParsed = emailSchema.array().safeParse(value); const emailsParsed = emailSchema.array().safeParse(value);
if (!emailsParsed.success) { if (!emailsParsed.success) {
@@ -217,9 +230,9 @@ function preprocess<T extends z.ZodType>({
return; return;
} }
if ( // Use fieldTypeConfig.propsType to validate for propsType=="text" or propsType=="select" as in those cases, the response would be a string.
["address", "text", "select", "name", "number", "radio", "textarea"].includes(bookingField.type) // If say we want to do special validation for 'address' that can be added to `fieldTypesSchemaMap`
) { if (["address", "text", "select", "number", "radio", "textarea"].includes(bookingField.type)) {
const schema = stringSchema; const schema = stringSchema;
if (!schema.safeParse(value).success) { if (!schema.safeParse(value).success) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: m("Invalid string") }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: m("Invalid string") });
@@ -1,6 +1,6 @@
import type z from "zod"; import type z from "zod";
import { SystemField } from "@calcom/features/bookings/lib/getBookingFields"; import { SystemField } from "@calcom/features/bookings/lib/SystemField";
import type { bookingResponsesDbSchema } from "@calcom/features/bookings/lib/getBookingResponsesSchema"; import type { bookingResponsesDbSchema } from "@calcom/features/bookings/lib/getBookingResponsesSchema";
import { getBookingWithResponses } from "@calcom/lib/getBooking"; import { getBookingWithResponses } from "@calcom/lib/getBooking";
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
@@ -43,6 +43,7 @@ export const getCalEventResponses = ({
parsedBookingFields.forEach((field) => { parsedBookingFields.forEach((field) => {
const label = field.label || field.defaultLabel; const label = field.label || field.defaultLabel;
if (!label) { if (!label) {
//TODO: This error must be thrown while saving event-type as well so that such an event-type can't be saved
throw new Error('Missing label for booking field "' + field.name + '"'); throw new Error('Missing label for booking field "' + field.name + '"');
} }
@@ -22,6 +22,7 @@ import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger"; import logger from "@calcom/lib/logger";
import { handleRefundError } from "@calcom/lib/payment/handleRefundError"; import { handleRefundError } from "@calcom/lib/payment/handleRefundError";
import { getTranslation } from "@calcom/lib/server/i18n"; import { getTranslation } from "@calcom/lib/server/i18n";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma, { bookingMinimalSelect } from "@calcom/prisma"; import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import { BookingStatus, MembershipRole, WorkflowMethods, WebhookTriggerEvents } from "@calcom/prisma/enums"; import { BookingStatus, MembershipRole, WorkflowMethods, WebhookTriggerEvents } from "@calcom/prisma/enums";
import { schemaBookingCancelParams } from "@calcom/prisma/zod-utils"; import { schemaBookingCancelParams } from "@calcom/prisma/zod-utils";
@@ -44,6 +45,7 @@ async function getBookingToDelete(id: number | undefined, uid: string | undefine
credentials: true, // Not leaking at the moment, be careful with credentials: true, // Not leaking at the moment, be careful with
email: true, email: true,
timeZone: true, timeZone: true,
timeFormat: true,
name: true, name: true,
destinationCalendar: true, destinationCalendar: true,
}, },
@@ -154,6 +156,7 @@ async function handler(req: CustomRequest) {
name: true, name: true,
email: true, email: true,
timeZone: true, timeZone: true,
timeFormat: true,
locale: true, locale: true,
}, },
}); });
@@ -207,6 +210,7 @@ async function handler(req: CustomRequest) {
email: organizer.email, email: organizer.email,
name: organizer.name ?? "Nameless", name: organizer.name ?? "Nameless",
timeZone: organizer.timeZone, timeZone: organizer.timeZone,
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
language: { translate: tOrganizer, locale: organizer.locale ?? "en" }, language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
}, },
attendees: attendeesList, attendees: attendeesList,
@@ -540,6 +544,7 @@ async function handler(req: CustomRequest) {
email: bookingToDelete.user?.email ?? "dev@calendso.com", email: bookingToDelete.user?.email ?? "dev@calendso.com",
name: bookingToDelete.user?.name ?? "no user", name: bookingToDelete.user?.name ?? "no user",
timeZone: bookingToDelete.user?.timeZone ?? "", timeZone: bookingToDelete.user?.timeZone ?? "",
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
language: { translate: tOrganizer, locale: organizer.locale ?? "en" }, language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
}, },
attendees: attendeesList, attendees: attendeesList,
@@ -42,6 +42,7 @@ import { deleteScheduledEmailReminder } from "@calcom/features/ee/workflows/lib/
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler"; import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
import { deleteScheduledSMSReminder } from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager"; import { deleteScheduledSMSReminder } from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
import { deleteScheduledWhatsappReminder } from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager"; import { deleteScheduledWhatsappReminder } from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
import { getFullName } from "@calcom/features/form-builder/utils";
import type { GetSubscriberOptions } from "@calcom/features/webhooks/lib/getWebhooks"; import type { GetSubscriberOptions } from "@calcom/features/webhooks/lib/getWebhooks";
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib"; import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
@@ -60,7 +61,7 @@ import { getBookerUrl } from "@calcom/lib/server/getBookerUrl";
import { getTranslation } from "@calcom/lib/server/i18n"; import { getTranslation } from "@calcom/lib/server/i18n";
import { slugify } from "@calcom/lib/slugify"; import { slugify } from "@calcom/lib/slugify";
import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager"; import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager";
import { TimeFormat } from "@calcom/lib/timeFormat"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma, { userSelect } from "@calcom/prisma"; import prisma, { userSelect } from "@calcom/prisma";
import type { BookingReference } from "@calcom/prisma/client"; import type { BookingReference } from "@calcom/prisma/client";
import { BookingStatus, SchedulingType, WebhookTriggerEvents, WorkflowMethods } from "@calcom/prisma/enums"; import { BookingStatus, SchedulingType, WebhookTriggerEvents, WorkflowMethods } from "@calcom/prisma/enums";
@@ -598,6 +599,7 @@ function getBookingData({
throw new Error("`responses` must not be nullish"); throw new Error("`responses` must not be nullish");
} }
const responses = reqBody.responses; const responses = reqBody.responses;
const { userFieldsResponses: calEventUserFieldsResponses, responses: calEventResponses } = const { userFieldsResponses: calEventUserFieldsResponses, responses: calEventResponses } =
getCalEventResponses({ getCalEventResponses({
bookingFields: eventType.bookingFields, bookingFields: eventType.bookingFields,
@@ -722,6 +724,8 @@ async function handler(
eventType, eventType,
}); });
const fullName = getFullName(bookerName);
const tAttendees = await getTranslation(language ?? "en", "common"); const tAttendees = await getTranslation(language ?? "en", "common");
const tGuests = await getTranslation("en", "common"); const tGuests = await getTranslation("en", "common");
log.debug(`Booking eventType ${eventTypeId} started`); log.debug(`Booking eventType ${eventTypeId} started`);
@@ -937,7 +941,7 @@ async function handler(
const invitee = [ const invitee = [
{ {
email: bookerEmail, email: bookerEmail,
name: bookerName, name: fullName,
timeZone: reqBody.timeZone, timeZone: reqBody.timeZone,
language: { translate: tAttendees, locale: language ?? "en" }, language: { translate: tAttendees, locale: language ?? "en" },
}, },
@@ -990,9 +994,11 @@ async function handler(
const eventNameObject = { const eventNameObject = {
//TODO: Can we have an unnamed attendee? If not, I would really like to throw an error here. //TODO: Can we have an unnamed attendee? If not, I would really like to throw an error here.
attendeeName: bookerName || "Nameless", attendeeName: fullName || "Nameless",
eventType: eventType.title, eventType: eventType.title,
eventName: eventType.eventName, eventName: eventType.eventName,
// we send on behalf of team if >1 round robin attendee | collective
teamName: eventType.schedulingType === "COLLECTIVE" || users.length > 1 ? eventType.team?.name : null,
// TODO: Can we have an unnamed organizer? If not, I would really like to throw an error here. // TODO: Can we have an unnamed organizer? If not, I would really like to throw an error here.
host: organizerUser.name || "Nameless", host: organizerUser.name || "Nameless",
location: bookingLocation, location: bookingLocation,
@@ -1027,7 +1033,7 @@ async function handler(
username: organizerUser.username || undefined, username: organizerUser.username || undefined,
timeZone: organizerUser.timeZone, timeZone: organizerUser.timeZone,
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" }, language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
timeFormat: organizerUser.timeFormat === 24 ? TimeFormat.TWENTY_FOUR_HOUR : TimeFormat.TWELVE_HOUR, timeFormat: getTimeFormatStringFromUserTimeFormat(organizerUser.timeFormat),
}, },
responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null, responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null,
userFieldsResponses: calEventUserFieldsResponses, userFieldsResponses: calEventUserFieldsResponses,
@@ -49,7 +49,7 @@ export function DateValues({ days, containerNavRef }: Props) {
<span <span
className={classNames( className={classNames(
"items-center justify-center p-1", "items-center justify-center p-1",
isToday && "bg-inverted text-inverted rounded-full" isToday && "bg-brand-default text-brand rounded-full"
)}> )}>
{day.format("DD")} {day.format("DD")}
</span> </span>
@@ -101,7 +101,7 @@ function Cell({ isDisabled, topOffsetMinutes, timeSlot }: CellProps) {
{!isDisabled && hoverEventDuration !== 0 && ( {!isDisabled && hoverEventDuration !== 0 && (
<div <div
className={classNames( className={classNames(
"opacity-4 bg-subtle hover:bg-emphasis text-emphasis dark:border-emphasis absolute hidden rounded-[4px] border-[1px] border-gray-900 px-[6px] py-1 text-xs font-semibold leading-5 group-hover:flex group-hover:cursor-pointer", "opacity-4 bg-brand-default hover:bg-brand-default text-brand dark:border-emphasis absolute hidden rounded-[4px] border-[1px] border-gray-900 px-[6px] py-1 text-xs font-semibold leading-5 group-hover:flex group-hover:cursor-pointer",
hoverEventDuration && hoverEventDuration > 15 && "items-start pt-3", hoverEventDuration && hoverEventDuration > 15 && "items-start pt-3",
hoverEventDuration && hoverEventDuration < 15 && "items-center" hoverEventDuration && hoverEventDuration < 15 && "items-center"
)} )}
@@ -223,8 +223,11 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
defaultValue={value} defaultValue={value}
onChange={(e) => { onChange={(e) => {
const domain = extractDomainFromEmail(e?.target.value); const domain = extractDomainFromEmail(e?.target.value);
newOrganizationFormMethods.setValue("adminEmail", e?.target.value); newOrganizationFormMethods.setValue("adminEmail", e?.target.value.trim());
newOrganizationFormMethods.setValue("adminUsername", e?.target.value.split("@")[0]); newOrganizationFormMethods.setValue(
"adminUsername",
e?.target.value.split("@")[0].trim()
);
if (newOrganizationFormMethods.getValues("slug") === "") { if (newOrganizationFormMethods.getValues("slug") === "") {
newOrganizationFormMethods.setValue("slug", domain); newOrganizationFormMethods.setValue("slug", domain);
} }
@@ -256,7 +259,7 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
label={t("organization_name")} label={t("organization_name")}
defaultValue={value} defaultValue={value}
onChange={(e) => { onChange={(e) => {
newOrganizationFormMethods.setValue("name", e?.target.value); newOrganizationFormMethods.setValue("name", e?.target.value.trim());
if (newOrganizationFormMethods.formState.touchedFields["slug"] === undefined) { if (newOrganizationFormMethods.formState.touchedFields["slug"] === undefined) {
newOrganizationFormMethods.setValue("slug", slugify(e?.target.value)); newOrganizationFormMethods.setValue("slug", slugify(e?.target.value));
} }
@@ -1,133 +1,17 @@
import { useRouter } from "next/router";
import { useState } from "react";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired"; import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import MemberInvitationModal from "@calcom/features/ee/teams/components/MemberInvitationModal";
import MemberListItem from "@calcom/features/ee/teams/components/MemberListItem";
import TeamInviteList from "@calcom/features/ee/teams/components/TeamInviteList";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout"; import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { UserListTable } from "@calcom/features/users/components/UserTable/UserListTable";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { MembershipRole } from "@calcom/prisma/enums"; import { Meta } from "@calcom/ui";
import { trpc } from "@calcom/trpc/react";
import type { RouterOutputs } from "@calcom/trpc/react";
import { Button, Meta, TextField, showToast } from "@calcom/ui";
import { Plus } from "@calcom/ui/components/icon";
type Team = RouterOutputs["viewer"]["teams"]["get"];
interface MembersListProps {
team: Team | undefined;
}
const checkIfExist = (comp: string, query: string) =>
comp.toLowerCase().replace(/\s+/g, "").includes(query.toLowerCase().replace(/\s+/g, ""));
function MembersList(props: MembersListProps) {
const { team } = props;
const { t } = useLocale();
const [query, setQuery] = useState<string>("");
const members = team?.members;
const membersList = members
? members && query === ""
? members
: members.filter((member) => {
const email = member.email ? checkIfExist(member.email, query) : false;
const username = member.username ? checkIfExist(member.username, query) : false;
const name = member.name ? checkIfExist(member.name, query) : false;
return email || username || name;
})
: undefined;
return (
<div className="flex flex-col gap-y-3">
<TextField
type="search"
autoComplete="false"
onChange={(e) => setQuery(e.target.value)}
value={query}
placeholder={`${t("search")}...`}
/>
{membersList?.length && team ? (
<ul className="divide-subtle border-subtle divide-y rounded-md border ">
{membersList.map((member) => {
return <MemberListItem key={member.id} team={team} member={member} />;
})}
</ul>
) : null}
</div>
);
}
const MembersView = () => { const MembersView = () => {
const { t, i18n } = useLocale(); const { t } = useLocale();
const router = useRouter();
const utils = trpc.useContext();
const showDialog = router.query.inviteModal === "true";
const [showMemberInvitationModal, setShowMemberInvitationModal] = useState(showDialog);
const { data: team, isLoading } = trpc.viewer.organizations.listMembers.useQuery(undefined, {
onError: () => {
router.push("/settings");
},
});
const inviteMemberMutation = trpc.viewer.teams.inviteMember.useMutation({
async onSuccess(data) {
await utils.viewer.organizations.listMembers.invalidate();
setShowMemberInvitationModal(false);
if (data.sendEmailInvitation) {
if (Array.isArray(data.usernameOrEmail)) {
showToast(
t("email_invite_team_bulk", {
userCount: data.usernameOrEmail.length,
}),
"success"
);
} else {
showToast(
t("email_invite_team", {
email: data.usernameOrEmail,
}),
"success"
);
}
}
},
onError: (error) => {
showToast(error.message, "error");
},
});
const isInviteOpen = !team?.membership.accepted;
const isAdminOrOwner =
team && (team.membership.role === MembershipRole.OWNER || team.membership.role === MembershipRole.ADMIN);
return ( return (
<LicenseRequired> <LicenseRequired>
<Meta <Meta title={t("organization_members")} description={t("organization_description")} />
title={t("organization_members")} <div>
description={t("organization_description")} {/* {team && (
CTA={
isAdminOrOwner ? (
<Button
type="button"
color="primary"
StartIcon={Plus}
className="ml-auto"
onClick={() => setShowMemberInvitationModal(true)}
data-testid="new-organization-member-button">
{t("add")}
</Button>
) : (
<></>
)
}
/>
{!isLoading && (
<>
<div>
{team && (
<> <>
{isInviteOpen && ( {isInviteOpen && (
<TeamInviteList <TeamInviteList
@@ -144,30 +28,9 @@ const MembersView = () => {
/> />
)} )}
</> </>
)} )} */}
<MembersList team={team} /> <UserListTable />
</div> </div>
{showMemberInvitationModal && team && (
<MemberInvitationModal
teamId={team.id}
isOpen={showMemberInvitationModal}
members={team.members}
onExit={() => setShowMemberInvitationModal(false)}
isLoading={inviteMemberMutation.isLoading}
onSubmit={(values) => {
inviteMemberMutation.mutate({
teamId: team.id,
language: i18n.language,
role: values.role,
usernameOrEmail: values.emailOrUsername,
sendEmailInvitation: values.sendInviteEmail,
isOrg: true,
});
}}
/>
)}
</>
)}
</LicenseRequired> </LicenseRequired>
); );
}; };
@@ -14,6 +14,7 @@ import { IS_PRODUCTION } from "@calcom/lib/constants";
import { getErrorFromUnknown } from "@calcom/lib/errors"; import { getErrorFromUnknown } from "@calcom/lib/errors";
import { HttpError as HttpCode } from "@calcom/lib/http-error"; import { HttpError as HttpCode } from "@calcom/lib/http-error";
import { getTranslation } from "@calcom/lib/server/i18n"; import { getTranslation } from "@calcom/lib/server/i18n";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { prisma, bookingMinimalSelect } from "@calcom/prisma"; import { prisma, bookingMinimalSelect } from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/enums"; import { BookingStatus } from "@calcom/prisma/enums";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
@@ -59,6 +60,7 @@ async function getBooking(bookingId: number) {
id: true, id: true,
username: true, username: true,
timeZone: true, timeZone: true,
timeFormat: true,
email: true, email: true,
name: true, name: true,
locale: true, locale: true,
@@ -108,6 +110,7 @@ async function getBooking(bookingId: number) {
email: user.email, email: user.email,
name: user.name!, name: user.name!,
timeZone: user.timeZone, timeZone: user.timeZone,
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
language: { translate: t, locale: user.locale ?? "en" }, language: { translate: t, locale: user.locale ?? "en" },
id: user.id, id: user.id,
}, },
@@ -163,6 +166,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
username: true, username: true,
credentials: true, credentials: true,
timeZone: true, timeZone: true,
timeFormat: true,
email: true, email: true,
name: true, name: true,
locale: true, locale: true,
@@ -216,6 +220,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
email: user.email, email: user.email,
name: user.name!, name: user.name!,
timeZone: user.timeZone, timeZone: user.timeZone,
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
language: { translate: t, locale: user.locale ?? "en" }, language: { translate: t, locale: user.locale ?? "en" },
}, },
attendees: attendeesList, attendees: attendeesList,
@@ -11,7 +11,7 @@ import type { StripePaymentData, StripeSetupIntentData } from "@calcom/app-store
import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect"; import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { CAL_URL } from "@calcom/lib/constants"; import { CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Checkbox } from "@calcom/ui"; import { Button, CheckboxField } from "@calcom/ui";
import type { EventType } from ".prisma/client"; import type { EventType } from ".prisma/client";
@@ -101,7 +101,7 @@ const PaymentForm = (props: Props) => {
</div> </div>
{paymentOption === "HOLD" && ( {paymentOption === "HOLD" && (
<div className="bg-info mb-5 mt-2 rounded-md p-3"> <div className="bg-info mb-5 mt-2 rounded-md p-3">
<Checkbox <CheckboxField
description={t("acknowledge_booking_no_show_fee", { description={t("acknowledge_booking_no_show_fee", {
amount: props.payment.amount / 100, amount: props.payment.amount / 100,
formatParams: { amount: { currency: props.payment.currency } }, formatParams: { amount: { currency: props.payment.currency } },
@@ -116,8 +116,7 @@ const PaymentForm = (props: Props) => {
color="minimal" color="minimal"
disabled={!holdAcknowledged || ["processing", "error"].includes(state.status)} disabled={!holdAcknowledged || ["processing", "error"].includes(state.status)}
id="cancel" id="cancel"
onClick={() => router.back()} onClick={() => router.back()}>
>
<span id="button-text">{t("cancel")}</span> <span id="button-text">{t("cancel")}</span>
</Button> </Button>
<Button <Button
@@ -102,7 +102,7 @@ export default function MemberChangeRoleModal(props: {
{errorMessage} {errorMessage}
</p> </p>
)} )}
<DialogFooter showDivider className="mt-12 sm:flex sm:flex-row-reverse"> <DialogFooter className="mt-12">
<Button type="button" color="secondary" onClick={props.onExit}> <Button type="button" color="secondary" onClick={props.onExit}>
{t("cancel")} {t("cancel")}
</Button> </Button>
@@ -13,7 +13,7 @@ import type { RouterOutputs } from "@calcom/trpc";
import { trpc } from "@calcom/trpc"; import { trpc } from "@calcom/trpc";
import { import {
Button, Button,
Checkbox as CheckboxField, CheckboxField,
Dialog, Dialog,
DialogContent, DialogContent,
DialogFooter, DialogFooter,
@@ -6,6 +6,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs"; import dayjs from "@calcom/dayjs";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import { defaultHandler } from "@calcom/lib/server"; import { defaultHandler } from "@calcom/lib/server";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums"; import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
@@ -196,6 +197,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
reminder.workflowStep.emailSubject || "", reminder.workflowStep.emailSubject || "",
variables, variables,
emailLocale, emailLocale,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
!!reminder.booking.user?.hideBranding !!reminder.booking.user?.hideBranding
).text; ).text;
emailContent.emailSubject = emailSubject; emailContent.emailSubject = emailSubject;
@@ -203,16 +205,22 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
reminder.workflowStep.reminderBody || "", reminder.workflowStep.reminderBody || "",
variables, variables,
emailLocale, emailLocale,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
!!reminder.booking.user?.hideBranding !!reminder.booking.user?.hideBranding
).html; ).html;
emailBodyEmpty = emailBodyEmpty =
customTemplate(reminder.workflowStep.reminderBody || "", variables, emailLocale).text.length === customTemplate(
0; reminder.workflowStep.reminderBody || "",
variables,
emailLocale,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
).text.length === 0;
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) { } else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
emailContent = emailReminderTemplate( emailContent = emailReminderTemplate(
false, false,
reminder.workflowStep.action, reminder.workflowStep.action,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
reminder.booking.startTime.toISOString() || "", reminder.booking.startTime.toISOString() || "",
reminder.booking.endTime.toISOString() || "", reminder.booking.endTime.toISOString() || "",
reminder.booking.eventType?.title || "", reminder.booking.eventType?.title || "",
@@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs"; import dayjs from "@calcom/dayjs";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import { defaultHandler } from "@calcom/lib/server"; import { defaultHandler } from "@calcom/lib/server";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums"; import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
@@ -116,13 +117,15 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const customMessage = customTemplate( const customMessage = customTemplate(
reminder.workflowStep.reminderBody || "", reminder.workflowStep.reminderBody || "",
variables, variables,
locale || "en" locale || "en",
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
); );
message = customMessage.text; message = customMessage.text;
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) { } else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
message = smsReminderTemplate( message = smsReminderTemplate(
false, false,
reminder.workflowStep.action, reminder.workflowStep.action,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
reminder.booking?.startTime.toISOString() || "", reminder.booking?.startTime.toISOString() || "",
reminder.booking?.eventType?.title || "", reminder.booking?.eventType?.title || "",
timeZone || "", timeZone || "",
@@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs"; import dayjs from "@calcom/dayjs";
import { defaultHandler } from "@calcom/lib/server"; import { defaultHandler } from "@calcom/lib/server";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { getWhatsappTemplateFunction } from "../lib/actionHelperFunctions"; import { getWhatsappTemplateFunction } from "../lib/actionHelperFunctions";
@@ -81,6 +82,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const message = templateFunction( const message = templateFunction(
false, false,
reminder.workflowStep.action, reminder.workflowStep.action,
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
reminder.booking?.startTime.toISOString() || "", reminder.booking?.startTime.toISOString() || "",
reminder.booking?.eventType?.title || "", reminder.booking?.eventType?.title || "",
timeZone || "", timeZone || "",
@@ -11,7 +11,7 @@ import { WorkflowActions } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import { import {
Button, Button,
Checkbox, CheckboxField,
Dialog, Dialog,
DialogClose, DialogClose,
DialogContent, DialogContent,
@@ -93,7 +93,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
setIsPhoneNumberNeeded(true); setIsPhoneNumberNeeded(true);
setIsSenderIdNeeded(true); setIsSenderIdNeeded(true);
setIsEmailAddressNeeded(false); setIsEmailAddressNeeded(false);
form.resetField("senderId", { defaultValue: SENDER_ID }) form.resetField("senderId", { defaultValue: SENDER_ID });
} else if (newValue.value === WorkflowActions.EMAIL_ADDRESS) { } else if (newValue.value === WorkflowActions.EMAIL_ADDRESS) {
setIsEmailAddressNeeded(true); setIsEmailAddressNeeded(true);
setIsSenderIdNeeded(false); setIsSenderIdNeeded(false);
@@ -102,7 +102,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
setIsSenderIdNeeded(true); setIsSenderIdNeeded(true);
setIsEmailAddressNeeded(false); setIsEmailAddressNeeded(false);
setIsPhoneNumberNeeded(false); setIsPhoneNumberNeeded(false);
form.resetField("senderId", { defaultValue: SENDER_ID }) form.resetField("senderId", { defaultValue: SENDER_ID });
} else if (newValue.value === WorkflowActions.WHATSAPP_NUMBER) { } else if (newValue.value === WorkflowActions.WHATSAPP_NUMBER) {
setIsSenderIdNeeded(false); setIsSenderIdNeeded(false);
setIsPhoneNumberNeeded(true); setIsPhoneNumberNeeded(true);
@@ -123,17 +123,16 @@ export const AddActionDialog = (props: IAddActionDialog) => {
const canRequirePhoneNumber = (workflowStep: string) => { const canRequirePhoneNumber = (workflowStep: string) => {
return ( return (
WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
WorkflowActions.WHATSAPP_ATTENDEE === workflowStep );
) };
}
const showSender = (action: string) => { const showSender = (action: string) => {
return !isSenderIdNeeded && !( return (
WorkflowActions.WHATSAPP_NUMBER === action || !isSenderIdNeeded &&
WorkflowActions.WHATSAPP_ATTENDEE === action !(WorkflowActions.WHATSAPP_NUMBER === action || WorkflowActions.WHATSAPP_ATTENDEE === action)
) );
} };
return ( return (
<Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}> <Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}>
@@ -186,7 +185,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
{isPhoneNumberNeeded && ( {isPhoneNumberNeeded && (
<div className="mt-5 space-y-1"> <div className="mt-5 space-y-1">
<Label htmlFor="sendTo">{t("phone_number")}</Label> <Label htmlFor="sendTo">{t("phone_number")}</Label>
<div className="mt-1 mb-5"> <div className="mb-5 mt-1">
<Controller <Controller
control={form.control} control={form.control}
name="sendTo" name="sendTo"
@@ -228,7 +227,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
)} )}
</> </>
)} )}
{showSender(form.getValues('action')) && ( {showSender(form.getValues("action")) && (
<div className="mt-5"> <div className="mt-5">
<Label>{t("sender_name")}</Label> <Label>{t("sender_name")}</Label>
<Input type="text" placeholder={SENDER_NAME} {...form.register(`senderName`)} /> <Input type="text" placeholder={SENDER_NAME} {...form.register(`senderName`)} />
@@ -240,7 +239,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
name="numberRequired" name="numberRequired"
control={form.control} control={form.control}
render={() => ( render={() => (
<Checkbox <CheckboxField
defaultChecked={form.getValues("numberRequired") || false} defaultChecked={form.getValues("numberRequired") || false}
description={t("make_phone_number_required")} description={t("make_phone_number_required")}
onChange={(e) => form.setValue("numberRequired", e.target.checked)} onChange={(e) => form.setValue("numberRequired", e.target.checked)}
@@ -9,6 +9,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WorkflowTemplates } from "@calcom/prisma/enums"; import { WorkflowTemplates } from "@calcom/prisma/enums";
import type { WorkflowActions } from "@calcom/prisma/enums"; import type { WorkflowActions } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import type { RouterOutputs } from "@calcom/trpc/react";
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui"; import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
import { Button, Label, MultiSelectCheckboxes, TextField } from "@calcom/ui"; import { Button, Label, MultiSelectCheckboxes, TextField } from "@calcom/ui";
import { ArrowDown, Trash2 } from "@calcom/ui/components/icon"; import { ArrowDown, Trash2 } from "@calcom/ui/components/icon";
@@ -19,12 +20,15 @@ import { AddActionDialog } from "./AddActionDialog";
import { DeleteDialog } from "./DeleteDialog"; import { DeleteDialog } from "./DeleteDialog";
import WorkflowStepContainer from "./WorkflowStepContainer"; import WorkflowStepContainer from "./WorkflowStepContainer";
type User = RouterOutputs["viewer"]["me"];
interface Props { interface Props {
form: UseFormReturn<FormValues>; form: UseFormReturn<FormValues>;
workflowId: number; workflowId: number;
selectedEventTypes: Option[]; selectedEventTypes: Option[];
setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>; setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>;
teamId?: number; teamId?: number;
user: User;
isMixedEventType: boolean; isMixedEventType: boolean;
readOnly: boolean; readOnly: boolean;
} }
@@ -158,7 +162,7 @@ export default function WorkflowDetailsPage(props: Props) {
<div className="bg-muted border-subtle w-full rounded-md border p-3 py-5 md:ml-3 md:p-8"> <div className="bg-muted border-subtle w-full rounded-md border p-3 py-5 md:ml-3 md:p-8">
{form.getValues("trigger") && ( {form.getValues("trigger") && (
<div> <div>
<WorkflowStepContainer form={form} teamId={teamId} readOnly={props.readOnly} /> <WorkflowStepContainer form={form} user={props.user} teamId={teamId} readOnly={props.readOnly} />
</div> </div>
)} )}
{form.getValues("steps") && ( {form.getValues("steps") && (
@@ -168,6 +172,7 @@ export default function WorkflowDetailsPage(props: Props) {
<WorkflowStepContainer <WorkflowStepContainer
key={step.id} key={step.id}
form={form} form={form}
user={props.user}
step={step} step={step}
reload={reload} reload={reload}
setReload={setReload} setReload={setReload}
@@ -9,13 +9,15 @@ import { classNames } from "@calcom/lib";
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants"; import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error"; import { HttpError } from "@calcom/lib/http-error";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { WorkflowTemplates, TimeUnit, WorkflowActions } from "@calcom/prisma/enums"; import { WorkflowTemplates, TimeUnit, WorkflowActions } from "@calcom/prisma/enums";
import { WorkflowTriggerEvents } from "@calcom/prisma/enums"; import { WorkflowTriggerEvents } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import type { RouterOutputs } from "@calcom/trpc/react";
import { import {
Badge, Badge,
Button, Button,
Checkbox, CheckboxField,
Dialog, Dialog,
DialogClose, DialogClose,
DialogContent, DialogContent,
@@ -39,8 +41,14 @@ import {
} from "@calcom/ui"; } from "@calcom/ui";
import { ArrowDown, MoreHorizontal, Trash2, HelpCircle, Info } from "@calcom/ui/components/icon"; import { ArrowDown, MoreHorizontal, Trash2, HelpCircle, Info } from "@calcom/ui/components/icon";
import {
isAttendeeAction,
isSMSAction,
isSMSOrWhatsappAction,
isWhatsappAction,
getWhatsappTemplateForAction,
} from "../lib/actionHelperFunctions";
import { DYNAMIC_TEXT_VARIABLES } from "../lib/constants"; import { DYNAMIC_TEXT_VARIABLES } from "../lib/constants";
import { isAttendeeAction, isSMSAction, isSMSOrWhatsappAction, isWhatsappAction, getWhatsappTemplateForAction } from "../lib/actionHelperFunctions";
import { getWorkflowTemplateOptions, getWorkflowTriggerOptions } from "../lib/getOptions"; import { getWorkflowTemplateOptions, getWorkflowTriggerOptions } from "../lib/getOptions";
import emailReminderTemplate from "../lib/reminders/templates/emailReminderTemplate"; import emailReminderTemplate from "../lib/reminders/templates/emailReminderTemplate";
import smsReminderTemplate from "../lib/reminders/templates/smsReminderTemplate"; import smsReminderTemplate from "../lib/reminders/templates/smsReminderTemplate";
@@ -48,9 +56,12 @@ import { whatsappReminderTemplate } from "../lib/reminders/templates/whatsapp";
import type { FormValues } from "../pages/workflow"; import type { FormValues } from "../pages/workflow";
import { TimeTimeUnitInput } from "./TimeTimeUnitInput"; import { TimeTimeUnitInput } from "./TimeTimeUnitInput";
type User = RouterOutputs["viewer"]["me"];
type WorkflowStepProps = { type WorkflowStepProps = {
step?: WorkflowStep; step?: WorkflowStep;
form: UseFormReturn<FormValues>; form: UseFormReturn<FormValues>;
user: User;
reload?: boolean; reload?: boolean;
setReload?: Dispatch<SetStateAction<boolean>>; setReload?: Dispatch<SetStateAction<boolean>>;
teamId?: number; teamId?: number;
@@ -66,19 +77,24 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
{ teamId }, { teamId },
{ enabled: !!teamId } { enabled: !!teamId }
); );
const timeFormat = getTimeFormatStringFromUserTimeFormat(props.user.timeFormat);
const verifiedNumbers = _verifiedNumbers?.map((number) => number.phoneNumber) || []; const verifiedNumbers = _verifiedNumbers?.map((number) => number.phoneNumber) || [];
const [isAdditionalInputsDialogOpen, setIsAdditionalInputsDialogOpen] = useState(false); const [isAdditionalInputsDialogOpen, setIsAdditionalInputsDialogOpen] = useState(false);
const [verificationCode, setVerificationCode] = useState(""); const [verificationCode, setVerificationCode] = useState("");
const action = step?.action const action = step?.action;
const requirePhoneNumber = WorkflowActions.SMS_NUMBER === action || WorkflowActions.WHATSAPP_NUMBER === action; const requirePhoneNumber =
WorkflowActions.SMS_NUMBER === action || WorkflowActions.WHATSAPP_NUMBER === action;
const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(requirePhoneNumber); const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(requirePhoneNumber);
const [updateTemplate, setUpdateTemplate] = useState(false); const [updateTemplate, setUpdateTemplate] = useState(false);
const [firstRender, setFirstRender] = useState(true); const [firstRender, setFirstRender] = useState(true);
const senderNeeded = step?.action === WorkflowActions.SMS_NUMBER || step?.action === WorkflowActions.SMS_ATTENDEE; const senderNeeded =
step?.action === WorkflowActions.SMS_NUMBER || step?.action === WorkflowActions.SMS_ATTENDEE;
const [isSenderIsNeeded, setIsSenderIsNeeded] = useState(senderNeeded); const [isSenderIsNeeded, setIsSenderIsNeeded] = useState(senderNeeded);
@@ -110,33 +126,31 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
if (!form.getValues(`steps.${step.stepNumber - 1}.reminderBody`)) { if (!form.getValues(`steps.${step.stepNumber - 1}.reminderBody`)) {
const action = form.getValues(`steps.${step.stepNumber - 1}.action`); const action = form.getValues(`steps.${step.stepNumber - 1}.action`);
if (isSMSAction(action)) { if (isSMSAction(action)) {
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, smsReminderTemplate( form.setValue(
true, `steps.${step.stepNumber - 1}.reminderBody`,
action smsReminderTemplate(true, action, timeFormat)
)); );
} else if (isWhatsappAction(action)) { } else if (isWhatsappAction(action)) {
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, whatsappReminderTemplate( form.setValue(
true, `steps.${step.stepNumber - 1}.reminderBody`,
action whatsappReminderTemplate(true, action, timeFormat)
)) );
} else { } else {
const reminderBodyTemplate = emailReminderTemplate( const reminderBodyTemplate = emailReminderTemplate(true, action, timeFormat).emailBody;
true,
action
).emailBody;
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, reminderBodyTemplate); form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, reminderBodyTemplate);
} }
} }
if (!form.getValues(`steps.${step.stepNumber - 1}.emailSubject`)) { if (!form.getValues(`steps.${step.stepNumber - 1}.emailSubject`)) {
const subjectTemplate = emailReminderTemplate( const subjectTemplate = emailReminderTemplate(
true, true,
form.getValues(`steps.${step.stepNumber - 1}.action`) form.getValues(`steps.${step.stepNumber - 1}.action`),
timeFormat
).emailSubject; ).emailSubject;
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, subjectTemplate); form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, subjectTemplate);
} }
} else if (step && isWhatsappAction(step.action)) { } else if (step && isWhatsappAction(step.action)) {
const templateBody = getWhatsappTemplateForAction(step.action, step.template) const templateBody = getWhatsappTemplateForAction(step.action, step.template, timeFormat);
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody) form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody);
} }
const { ref: emailSubjectFormRef, ...restEmailSubjectForm } = step const { ref: emailSubjectFormRef, ...restEmailSubjectForm } = step
@@ -151,7 +165,11 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
const refReminderBody = useRef<HTMLTextAreaElement | null>(null); const refReminderBody = useRef<HTMLTextAreaElement | null>(null);
const getNumberVerificationStatus = () => !!step && !!verifiedNumbers.find((number: string) => number === form.getValues(`steps.${step.stepNumber - 1}.sendTo`)) const getNumberVerificationStatus = () =>
!!step &&
!!verifiedNumbers.find(
(number: string) => number === form.getValues(`steps.${step.stepNumber - 1}.sendTo`)
);
const [numberVerified, setNumberVerified] = useState(getNumberVerificationStatus()); const [numberVerified, setNumberVerified] = useState(getNumberVerificationStatus());
@@ -236,17 +254,17 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
return ( return (
<> <>
<div className="flex justify-center"> <div className="flex justify-center">
<div className="w-full border rounded-md min-w-80 bg-default border-subtle p-7"> <div className="min-w-80 bg-default border-subtle w-full rounded-md border p-7">
<div className="flex"> <div className="flex">
<div className="bg-subtle text-default mt-[3px] flex h-5 w-5 items-center justify-center rounded-full p-1 text-xs font-medium ltr:mr-5 rtl:ml-5"> <div className="bg-subtle text-default mt-[3px] flex h-5 w-5 items-center justify-center rounded-full p-1 text-xs font-medium ltr:mr-5 rtl:ml-5">
1 1
</div> </div>
<div> <div>
<div className="text-base font-bold text-emphasis">{t("trigger")}</div> <div className="text-emphasis text-base font-bold">{t("trigger")}</div>
<div className="text-sm text-default">{t("when_something_happens")}</div> <div className="text-default text-sm">{t("when_something_happens")}</div>
</div> </div>
</div> </div>
<div className="border-t border-subtle my-7" /> <div className="border-subtle my-7 border-t" />
<Label>{t("when")}</Label> <Label>{t("when")}</Label>
<Controller <Controller
name="trigger" name="trigger"
@@ -291,7 +309,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<Label>{showTimeSectionAfter ? t("how_long_after") : t("how_long_before")}</Label> <Label>{showTimeSectionAfter ? t("how_long_after") : t("how_long_before")}</Label>
<TimeTimeUnitInput form={form} disabled={props.readOnly} /> <TimeTimeUnitInput form={form} disabled={props.readOnly} />
{!props.readOnly && ( {!props.readOnly && (
<div className="flex mt-1 text-gray-500"> <div className="mt-1 flex text-gray-500">
<Info className="mr-1 mt-0.5 h-4 w-4" /> <Info className="mr-1 mt-0.5 h-4 w-4" />
<p className="text-sm">{t("testing_workflow_info_message")}</p> <p className="text-sm">{t("testing_workflow_info_message")}</p>
</div> </div>
@@ -318,18 +336,17 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
const canRequirePhoneNumber = (workflowStep: string) => { const canRequirePhoneNumber = (workflowStep: string) => {
return ( return (
WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
WorkflowActions.WHATSAPP_ATTENDEE === workflowStep );
) };
}
return ( return (
<> <>
<div className="flex justify-center my-3"> <div className="my-3 flex justify-center">
<ArrowDown className="text-subtle stroke-[1.5px] text-3xl" /> <ArrowDown className="text-subtle stroke-[1.5px] text-3xl" />
</div> </div>
<div className="flex justify-center"> <div className="flex justify-center">
<div className="flex w-full border rounded-md min-w-80 bg-default border-subtle p-7"> <div className="min-w-80 bg-default border-subtle flex w-full rounded-md border p-7">
<div className="w-full"> <div className="w-full">
<div className="flex"> <div className="flex">
<div className="w-full"> <div className="w-full">
@@ -338,8 +355,8 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
{step.stepNumber + 1} {step.stepNumber + 1}
</div> </div>
<div> <div>
<div className="text-base font-bold text-emphasis">{t("action")}</div> <div className="text-emphasis text-base font-bold">{t("action")}</div>
<div className="text-sm text-default">{t("action_is_performed")}</div> <div className="text-default text-sm">{t("action_is_performed")}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -379,7 +396,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</div> </div>
)} )}
</div> </div>
<div className="border-t border-subtle my-7" /> <div className="border-subtle my-7 border-t" />
<div> <div>
<Label>{t("do_this")}</Label> <Label>{t("do_this")}</Label>
<Controller <Controller
@@ -395,16 +412,18 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
if (val) { if (val) {
const oldValue = form.getValues(`steps.${step.stepNumber - 1}.action`); const oldValue = form.getValues(`steps.${step.stepNumber - 1}.action`);
const setNumberRequiredConfigs = (phoneNumberIsNeeded: boolean, senderNeeded = true) => { const setNumberRequiredConfigs = (
phoneNumberIsNeeded: boolean,
senderNeeded = true
) => {
setIsSenderIsNeeded(senderNeeded); setIsSenderIsNeeded(senderNeeded);
setIsEmailAddressNeeded(false); setIsEmailAddressNeeded(false);
setIsPhoneNumberNeeded(phoneNumberIsNeeded); setIsPhoneNumberNeeded(phoneNumberIsNeeded);
setNumberVerified(getNumberVerificationStatus()); setNumberVerified(getNumberVerificationStatus());
} };
if (isSMSAction(val.value)) { if (isSMSAction(val.value)) {
setNumberRequiredConfigs(val.value === WorkflowActions.SMS_NUMBER);
setNumberRequiredConfigs(val.value === WorkflowActions.SMS_NUMBER)
// email action changes to sms action // email action changes to sms action
if (!isSMSAction(oldValue)) { if (!isSMSAction(oldValue)) {
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, ""); form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
@@ -459,15 +478,19 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
if (isSMSAction(val.value)) { if (isSMSAction(val.value)) {
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
smsReminderTemplate(true, val.value) smsReminderTemplate(true, val.value, timeFormat)
); );
} else if (isWhatsappAction(val.value)) { } else if (isWhatsappAction(val.value)) {
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
whatsappReminderTemplate(true, val.value) whatsappReminderTemplate(true, val.value, timeFormat)
); );
} else { } else {
const emailReminderBody = emailReminderTemplate(true, val.value); const emailReminderBody = emailReminderTemplate(
true,
val.value,
timeFormat
);
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
emailReminderBody.emailBody emailReminderBody.emailBody
@@ -501,7 +524,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
/> />
</div> </div>
{isPhoneNumberNeeded && ( {isPhoneNumberNeeded && (
<div className="p-4 pt-0 mt-2 rounded-md bg-muted"> <div className="bg-muted mt-2 rounded-md p-4 pt-0">
<Label className="pt-4">{t("custom_phone_number")}</Label> <Label className="pt-4">{t("custom_phone_number")}</Label>
<div className="block sm:flex"> <div className="block sm:flex">
<Controller <Controller
@@ -553,7 +576,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
) : ( ) : (
!props.readOnly && ( !props.readOnly && (
<> <>
<div className="flex mt-3"> <div className="mt-3 flex">
<TextField <TextField
className="rounded-r-none border-r-transparent" className="rounded-r-none border-r-transparent"
placeholder="Verification code" placeholder="Verification code"
@@ -589,50 +612,52 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
)} )}
</div> </div>
)} )}
{!isWhatsappAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (<div className="p-4 pt-0 mt-2 rounded-md bg-muted"> {!isWhatsappAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (
{isSenderIsNeeded ? ( <div className="bg-muted mt-2 rounded-md p-4 pt-0">
<> {isSenderIsNeeded ? (
<div className="pt-4"> <>
<div className="flex"> <div className="pt-4">
<Label>{t("sender_id")}</Label> <div className="flex">
<Tooltip content={t("sender_id_info")}> <Label>{t("sender_id")}</Label>
<Info className="ml-2 mr-1 mt-0.5 h-4 w-4 text-gray-500" /> <Tooltip content={t("sender_id_info")}>
</Tooltip> <Info className="ml-2 mr-1 mt-0.5 h-4 w-4 text-gray-500" />
</Tooltip>
</div>
<Input
type="text"
placeholder={SENDER_ID}
disabled={props.readOnly}
maxLength={11}
{...form.register(`steps.${step.stepNumber - 1}.sender`)}
/>
</div> </div>
<Input {form.formState.errors.steps &&
type="text" form.formState?.errors?.steps[step.stepNumber - 1]?.sender && (
placeholder={SENDER_ID} <p className="mt-1 text-xs text-red-500">{t("sender_id_error_message")}</p>
disabled={props.readOnly} )}
maxLength={11} </>
{...form.register(`steps.${step.stepNumber - 1}.sender`)} ) : (
/> <>
</div> <div className="pt-4">
{form.formState.errors.steps && <Label>{t("sender_name")}</Label>
form.formState?.errors?.steps[step.stepNumber - 1]?.sender && ( <Input
<p className="mt-1 text-xs text-red-500">{t("sender_id_error_message")}</p> type="text"
)} disabled={props.readOnly}
</> placeholder={SENDER_NAME}
) : ( {...form.register(`steps.${step.stepNumber - 1}.senderName`)}
<> />
<div className="pt-4"> </div>
<Label>{t("sender_name")}</Label> </>
<Input )}
type="text" </div>
disabled={props.readOnly} )}
placeholder={SENDER_NAME}
{...form.register(`steps.${step.stepNumber - 1}.senderName`)}
/>
</div>
</>
)}
</div>)}
{canRequirePhoneNumber(form.getValues(`steps.${step.stepNumber - 1}.action`)) && ( {canRequirePhoneNumber(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (
<div className="mt-2"> <div className="mt-2">
<Controller <Controller
name={`steps.${step.stepNumber - 1}.numberRequired`} name={`steps.${step.stepNumber - 1}.numberRequired`}
control={form.control} control={form.control}
render={() => ( render={() => (
<Checkbox <CheckboxField
disabled={props.readOnly} disabled={props.readOnly}
defaultChecked={ defaultChecked={
form.getValues(`steps.${step.stepNumber - 1}.numberRequired`) || false form.getValues(`steps.${step.stepNumber - 1}.numberRequired`) || false
@@ -647,7 +672,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</div> </div>
)} )}
{isEmailAddressNeeded && ( {isEmailAddressNeeded && (
<div className="p-4 mt-5 rounded-md bg-muted"> <div className="bg-muted mt-5 rounded-md p-4">
<EmailField <EmailField
required required
disabled={props.readOnly} disabled={props.readOnly}
@@ -669,40 +694,40 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
isDisabled={props.readOnly} isDisabled={props.readOnly}
onChange={(val) => { onChange={(val) => {
if (val) { if (val) {
const action = form.getValues(`steps.${step.stepNumber - 1}.action`) const action = form.getValues(`steps.${step.stepNumber - 1}.action`);
if (val.value === WorkflowTemplates.REMINDER) { if (val.value === WorkflowTemplates.REMINDER) {
if (isWhatsappAction(action)) { if (isWhatsappAction(action)) {
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
whatsappReminderTemplate( whatsappReminderTemplate(true, action, timeFormat)
true,
action
)
); );
} else if (isSMSAction(action)) { } else if (isSMSAction(action)) {
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
smsReminderTemplate(true,action) smsReminderTemplate(true, action, timeFormat)
); );
} else { } else {
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`, `steps.${step.stepNumber - 1}.reminderBody`,
emailReminderTemplate(true, action).emailBody emailReminderTemplate(true, action, timeFormat).emailBody
); );
form.setValue( form.setValue(
`steps.${step.stepNumber - 1}.emailSubject`, `steps.${step.stepNumber - 1}.emailSubject`,
emailReminderTemplate(true, action).emailSubject emailReminderTemplate(true, action, timeFormat).emailSubject
); );
} }
} else { } else {
if (isWhatsappAction(action)) { if (isWhatsappAction(action)) {
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, getWhatsappTemplateForAction(action, val.value)) form.setValue(
`steps.${step.stepNumber - 1}.reminderBody`,
getWhatsappTemplateForAction(action, val.value, timeFormat)
);
} else { } else {
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, ""); form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, ""); form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, "");
} }
} }
field.onChange(val.value) field.onChange(val.value);
form.setValue(`steps.${step.stepNumber - 1}.template`, val.value); form.setValue(`steps.${step.stepNumber - 1}.template`, val.value);
setUpdateTemplate(!updateTemplate); setUpdateTemplate(!updateTemplate);
} }
@@ -715,7 +740,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
}} }}
/> />
</div> </div>
<div className="pt-2 mt-2 rounded-md bg-muted md:p-6 md:pt-4"> <div className="bg-muted mt-2 rounded-md pt-2 md:p-6 md:pt-4">
{isEmailSubjectNeeded && ( {isEmailSubjectNeeded && (
<div className="mb-6"> <div className="mb-6">
<div className="flex items-center"> <div className="flex items-center">
@@ -755,7 +780,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
step.action !== WorkflowActions.SMS_NUMBER ? ( step.action !== WorkflowActions.SMS_NUMBER ? (
<> <>
<div className="mb-2 flex items-center pb-[1.5px]"> <div className="mb-2 flex items-center pb-[1.5px]">
<Label className="flex-none mb-0 "> <Label className="mb-0 flex-none ">
{isEmailSubjectNeeded ? t("email_body") : t("text_message")} {isEmailSubjectNeeded ? t("email_body") : t("text_message")}
</Label> </Label>
</div> </div>
@@ -795,7 +820,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
reminderBodyFormRef?.(e); reminderBodyFormRef?.(e);
refReminderBody.current = e; refReminderBody.current = e;
}} }}
className="h-24 my-0" className="my-0 h-24"
disabled={props.readOnly} disabled={props.readOnly}
required required
{...restReminderBodyForm} {...restReminderBodyForm}
@@ -811,7 +836,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
{!props.readOnly && ( {!props.readOnly && (
<div className="mt-3 "> <div className="mt-3 ">
<button type="button" onClick={() => setIsAdditionalInputsDialogOpen(true)}> <button type="button" onClick={() => setIsAdditionalInputsDialogOpen(true)}>
<div className="flex mt-2 text-sm text-default"> <div className="text-default mt-2 flex text-sm">
<HelpCircle className="mt-[3px] h-3 w-3 ltr:mr-2 rtl:ml-2" /> <HelpCircle className="mt-[3px] h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p className="text-left">{t("using_booking_questions_as_variables")}</p> <p className="text-left">{t("using_booking_questions_as_variables")}</p>
</div> </div>
@@ -920,26 +945,26 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</ConfirmationDialogContent> </ConfirmationDialogContent>
</Dialog> */} </Dialog> */}
<Dialog open={isAdditionalInputsDialogOpen} onOpenChange={setIsAdditionalInputsDialogOpen}> <Dialog open={isAdditionalInputsDialogOpen} onOpenChange={setIsAdditionalInputsDialogOpen}>
<DialogContent type="creation" className="sm:max-w-[610px]"> <DialogContent enableOverflow type="creation" className="sm:max-w-[610px]">
<div className="-m-3 h-[430px] overflow-x-hidden overflow-y-scroll sm:m-0"> <div>
<h1 className="w-full text-xl font-semibold ">{t("how_booking_questions_as_variables")}</h1> <h1 className="w-full text-xl font-semibold ">{t("how_booking_questions_as_variables")}</h1>
<div className="mb-6 rounded-md bg-muted-3 sm:p-4"> <div className="bg-muted-3 mb-6 rounded-md sm:p-4">
<p className="font-medium test-sm">{t("format")}</p> <p className="test-sm font-medium">{t("format")}</p>
<ul className="mt-2 ml-5 list-disc text-emphasis"> <ul className="text-emphasis ml-5 mt-2 list-disc">
<li>{t("uppercase_for_letters")}</li> <li>{t("uppercase_for_letters")}</li>
<li>{t("replace_whitespaces_underscores")}</li> <li>{t("replace_whitespaces_underscores")}</li>
<li>{t("ignore_special_characters_booking_questions")}</li> <li>{t("ignore_special_characters_booking_questions")}</li>
</ul> </ul>
<div className="mt-4"> <div className="mt-4">
<p className="w-full font-medium test-sm">{t("example_1")}</p> <p className="test-sm w-full font-medium">{t("example_1")}</p>
<div className="grid grid-cols-12 mt-2"> <div className="mt-2 grid grid-cols-12">
<div className="col-span-5 test-sm text-default ltr:mr-2 rtl:ml-2"> <div className="test-sm text-default col-span-5 ltr:mr-2 rtl:ml-2">
{t("booking_question_identifier")} {t("booking_question_identifier")}
</div> </div>
<div className="col-span-7 test-sm text-emphasis">{t("company_size")}</div> <div className="test-sm text-emphasis col-span-7">{t("company_size")}</div>
<div className="w-full col-span-5 test-sm text-default">{t("variable")}</div> <div className="test-sm text-default col-span-5 w-full">{t("variable")}</div>
<div className="col-span-7 break-words test-sm text-emphasis"> <div className="test-sm text-emphasis col-span-7 break-words">
{" "} {" "}
{`{${t("company_size") {`{${t("company_size")
.replace(/[^a-zA-Z0-9 ]/g, "") .replace(/[^a-zA-Z0-9 ]/g, "")
@@ -950,14 +975,14 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</div> </div>
</div> </div>
<div className="mt-4"> <div className="mt-4">
<p className="w-full font-medium test-sm">{t("example_2")}</p> <p className="test-sm w-full font-medium">{t("example_2")}</p>
<div className="grid grid-cols-12 mt-2"> <div className="mt-2 grid grid-cols-12">
<div className="col-span-5 test-sm text-default ltr:mr-2 rtl:ml-2"> <div className="test-sm text-default col-span-5 ltr:mr-2 rtl:ml-2">
{t("booking_question_identifier")} {t("booking_question_identifier")}
</div> </div>
<div className="col-span-7 test-sm text-emphasis">{t("what_help_needed")}</div> <div className="test-sm text-emphasis col-span-7">{t("what_help_needed")}</div>
<div className="col-span-5 test-sm text-default">{t("variable")}</div> <div className="test-sm text-default col-span-5">{t("variable")}</div>
<div className="col-span-7 break-words test-sm text-emphasis"> <div className="test-sm text-emphasis col-span-7 break-words">
{" "} {" "}
{`{${t("what_help_needed") {`{${t("what_help_needed")
.replace(/[^a-zA-Z0-9 ]/g, "") .replace(/[^a-zA-Z0-9 ]/g, "")
@@ -969,7 +994,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</div> </div>
</div> </div>
</div> </div>
<DialogFooter showDivider className="flex flex-row-reverse"> <DialogFooter showDivider>
<DialogClose color="primary" /> <DialogClose color="primary" />
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
@@ -1,5 +1,14 @@
import { WorkflowActions, WorkflowTemplates, WorkflowTriggerEvents } from "@prisma/client"; import type { WorkflowTriggerEvents } from "@prisma/client";
import { whatsappEventCancelledTemplate, whatsappEventCompletedTemplate, whatsappEventRescheduledTemplate, whatsappReminderTemplate } from "../lib/reminders/templates/whatsapp"; import { WorkflowActions, WorkflowTemplates } from "@prisma/client";
import type { TimeFormat } from "@calcom/lib/timeFormat";
import {
whatsappEventCancelledTemplate,
whatsappEventCompletedTemplate,
whatsappEventRescheduledTemplate,
whatsappReminderTemplate,
} from "../lib/reminders/templates/whatsapp";
export function isSMSAction(action: WorkflowActions) { export function isSMSAction(action: WorkflowActions) {
return action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.SMS_NUMBER; return action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.SMS_NUMBER;
@@ -10,46 +19,54 @@ export function isWhatsappAction(action: WorkflowActions) {
} }
export function isSMSOrWhatsappAction(action: WorkflowActions) { export function isSMSOrWhatsappAction(action: WorkflowActions) {
return isSMSAction(action) || isWhatsappAction(action) return isSMSAction(action) || isWhatsappAction(action);
} }
export function isAttendeeAction(action: WorkflowActions) { export function isAttendeeAction(action: WorkflowActions) {
return action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.EMAIL_ATTENDEE || action === WorkflowActions.WHATSAPP_ATTENDEE; return (
action === WorkflowActions.SMS_ATTENDEE ||
action === WorkflowActions.EMAIL_ATTENDEE ||
action === WorkflowActions.WHATSAPP_ATTENDEE
);
} }
export function getWhatsappTemplateForTrigger(trigger: WorkflowTriggerEvents): WorkflowTemplates { export function getWhatsappTemplateForTrigger(trigger: WorkflowTriggerEvents): WorkflowTemplates {
switch(trigger) { switch (trigger) {
case "NEW_EVENT": case "NEW_EVENT":
case "BEFORE_EVENT": case "BEFORE_EVENT":
return WorkflowTemplates.REMINDER return WorkflowTemplates.REMINDER;
case "AFTER_EVENT": case "AFTER_EVENT":
return WorkflowTemplates.COMPLETED return WorkflowTemplates.COMPLETED;
case "EVENT_CANCELLED": case "EVENT_CANCELLED":
return WorkflowTemplates.CANCELLED return WorkflowTemplates.CANCELLED;
case "RESCHEDULE_EVENT": case "RESCHEDULE_EVENT":
return WorkflowTemplates.RESCHEDULED return WorkflowTemplates.RESCHEDULED;
default: default:
return WorkflowTemplates.REMINDER return WorkflowTemplates.REMINDER;
} }
} }
export function getWhatsappTemplateFunction(template: WorkflowTemplates): typeof whatsappReminderTemplate { export function getWhatsappTemplateFunction(template: WorkflowTemplates): typeof whatsappReminderTemplate {
switch(template) { switch (template) {
case "CANCELLED": case "CANCELLED":
return whatsappEventCancelledTemplate return whatsappEventCancelledTemplate;
case "COMPLETED": case "COMPLETED":
return whatsappEventCompletedTemplate return whatsappEventCompletedTemplate;
case "RESCHEDULED": case "RESCHEDULED":
return whatsappEventRescheduledTemplate return whatsappEventRescheduledTemplate;
case "CUSTOM": case "CUSTOM":
case "REMINDER": case "REMINDER":
return whatsappReminderTemplate return whatsappReminderTemplate;
default: default:
return whatsappReminderTemplate return whatsappReminderTemplate;
} }
} }
export function getWhatsappTemplateForAction(action: WorkflowActions, template: WorkflowTemplates): string | null { export function getWhatsappTemplateForAction(
const templateFunction = getWhatsappTemplateFunction(template) action: WorkflowActions,
return templateFunction(true, action) template: WorkflowTemplates,
timeFormat: TimeFormat
): string | null {
const templateFunction = getWhatsappTemplateFunction(template);
return templateFunction(true, action, timeFormat);
} }
@@ -79,11 +79,13 @@ const noAlphanumericSenderIdSupport = [
"+216", "+216",
"+90", "+90",
"+256", "+256",
"+971",
"+598", "+598",
"+58", "+58",
"+84", "+84",
"+260", "+260",
"+61", "+61",
"+971", "+971",
"+420",
"+381",
"+65",
]; ];
@@ -25,19 +25,16 @@ export const WORKFLOW_TEMPLATES = [
WorkflowTemplates.REMINDER, WorkflowTemplates.REMINDER,
WorkflowTemplates.CANCELLED, WorkflowTemplates.CANCELLED,
WorkflowTemplates.COMPLETED, WorkflowTemplates.COMPLETED,
WorkflowTemplates.RESCHEDULED WorkflowTemplates.RESCHEDULED,
] as const; ] as const;
export const BASIC_WORKFLOW_TEMPLATES = [ export const BASIC_WORKFLOW_TEMPLATES = [WorkflowTemplates.CUSTOM, WorkflowTemplates.REMINDER] as const;
WorkflowTemplates.CUSTOM,
WorkflowTemplates.REMINDER,
] as const;
export const WHATSAPP_WORKFLOW_TEMPLATES = [ export const WHATSAPP_WORKFLOW_TEMPLATES = [
WorkflowTemplates.REMINDER, WorkflowTemplates.REMINDER,
WorkflowTemplates.COMPLETED, WorkflowTemplates.COMPLETED,
WorkflowTemplates.CANCELLED, WorkflowTemplates.CANCELLED,
WorkflowTemplates.RESCHEDULED WorkflowTemplates.RESCHEDULED,
] as const; ] as const;
export const DYNAMIC_TEXT_VARIABLES = [ export const DYNAMIC_TEXT_VARIABLES = [
@@ -1,9 +1,9 @@
import type { WorkflowStep } from "@prisma/client"; import type { WorkflowStep } from "@prisma/client";
import { isSMSOrWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
import { classNames } from "@calcom/lib"; import { classNames } from "@calcom/lib";
import { WorkflowActions } from "@calcom/prisma/enums"; import { WorkflowActions } from "@calcom/prisma/enums";
import { Zap, Smartphone, Mail, Bell } from "@calcom/ui/components/icon"; import { Zap, Smartphone, Mail, Bell } from "@calcom/ui/components/icon";
import { isSMSOrWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
export function getActionIcon(steps: WorkflowStep[], className?: string): JSX.Element { export function getActionIcon(steps: WorkflowStep[], className?: string): JSX.Element {
if (steps.length === 0) { if (steps.length === 0) {
@@ -3,7 +3,13 @@ import type { TFunction } from "next-i18next";
import { WorkflowActions } from "@calcom/prisma/enums"; import { WorkflowActions } from "@calcom/prisma/enums";
import { isSMSOrWhatsappAction, isWhatsappAction } from "./actionHelperFunctions"; import { isSMSOrWhatsappAction, isWhatsappAction } from "./actionHelperFunctions";
import { TIME_UNIT, WHATSAPP_WORKFLOW_TEMPLATES, WORKFLOW_ACTIONS, BASIC_WORKFLOW_TEMPLATES, WORKFLOW_TRIGGER_EVENTS } from "./constants"; import {
TIME_UNIT,
WHATSAPP_WORKFLOW_TEMPLATES,
WORKFLOW_ACTIONS,
BASIC_WORKFLOW_TEMPLATES,
WORKFLOW_TRIGGER_EVENTS,
} from "./constants";
export function getWorkflowActionOptions(t: TFunction, isTeamsPlan?: boolean) { export function getWorkflowActionOptions(t: TFunction, isTeamsPlan?: boolean) {
return WORKFLOW_ACTIONS.filter((action) => action !== WorkflowActions.EMAIL_ADDRESS) //removing EMAIL_ADDRESS for now due to abuse episode return WORKFLOW_ACTIONS.filter((action) => action !== WorkflowActions.EMAIL_ADDRESS) //removing EMAIL_ADDRESS for now due to abuse episode
@@ -33,7 +39,8 @@ export function getWorkflowTimeUnitOptions(t: TFunction) {
} }
export function getWorkflowTemplateOptions(t: TFunction, action: WorkflowActions | undefined) { export function getWorkflowTemplateOptions(t: TFunction, action: WorkflowActions | undefined) {
const TEMPLATES = (action && isWhatsappAction(action)) ? WHATSAPP_WORKFLOW_TEMPLATES : BASIC_WORKFLOW_TEMPLATES; const TEMPLATES =
action && isWhatsappAction(action) ? WHATSAPP_WORKFLOW_TEMPLATES : BASIC_WORKFLOW_TEMPLATES;
return TEMPLATES.map((template) => { return TEMPLATES.map((template) => {
return { label: t(`${template.toLowerCase()}`), value: template }; return { label: t(`${template.toLowerCase()}`), value: template };
}) as { label: string; value: any }[]; }) as { label: string; value: any }[];
@@ -104,13 +104,20 @@ export const scheduleEmailReminder = async (
? evt.attendees[0].language?.locale ? evt.attendees[0].language?.locale
: evt.organizer.language.locale; : evt.organizer.language.locale;
const emailSubjectTemplate = customTemplate(emailSubject, variables, locale); const emailSubjectTemplate = customTemplate(emailSubject, variables, locale, evt.organizer.timeFormat);
emailContent.emailSubject = emailSubjectTemplate.text; emailContent.emailSubject = emailSubjectTemplate.text;
emailContent.emailBody = customTemplate(emailBody, variables, locale, hideBranding).html; emailContent.emailBody = customTemplate(
emailBody,
variables,
locale,
evt.organizer.timeFormat,
hideBranding
).html;
} else if (template === WorkflowTemplates.REMINDER) { } else if (template === WorkflowTemplates.REMINDER) {
emailContent = emailReminderTemplate( emailContent = emailReminderTemplate(
false, false,
action, action,
evt.organizer.timeFormat,
startTime, startTime,
endTime, endTime,
evt.title, evt.title,
@@ -1,6 +1,7 @@
import type { Workflow, WorkflowsOnEventTypes, WorkflowStep } from "@prisma/client"; import type { Workflow, WorkflowsOnEventTypes, WorkflowStep } from "@prisma/client";
import type { MailData } from "@sendgrid/helpers/classes/mail"; import type { MailData } from "@sendgrid/helpers/classes/mail";
import { isWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants"; import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
import { WorkflowTriggerEvents } from "@calcom/prisma/enums"; import { WorkflowTriggerEvents } from "@calcom/prisma/enums";
import { WorkflowActions } from "@calcom/prisma/enums"; import { WorkflowActions } from "@calcom/prisma/enums";
@@ -10,8 +11,6 @@ import { scheduleEmailReminder } from "./emailReminderManager";
import { scheduleSMSReminder } from "./smsReminderManager"; import { scheduleSMSReminder } from "./smsReminderManager";
import { scheduleWhatsappReminder } from "./whatsappReminderManager"; import { scheduleWhatsappReminder } from "./whatsappReminderManager";
import { isWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
type ExtendedCalendarEvent = CalendarEvent & { type ExtendedCalendarEvent = CalendarEvent & {
metadata?: { videoCallUrl: string | undefined }; metadata?: { videoCallUrl: string | undefined };
eventType: { slug?: string }; eventType: { slug?: string };
@@ -113,7 +112,8 @@ export const scheduleWorkflowReminders = async (args: ScheduleWorkflowRemindersA
hideBranding hideBranding
); );
} else if (isWhatsappAction(step.action)) { } else if (isWhatsappAction(step.action)) {
const sendTo = step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo; const sendTo =
step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo;
await scheduleWhatsappReminder( await scheduleWhatsappReminder(
evt, evt,
sendTo, sendTo,
@@ -208,7 +208,8 @@ export const sendCancelledReminders = async (args: SendCancelledRemindersArgs) =
hideBranding hideBranding
); );
} else if (isWhatsappAction(step.action)) { } else if (isWhatsappAction(step.action)) {
const sendTo = step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo; const sendTo =
step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo;
await scheduleWhatsappReminder( await scheduleWhatsappReminder(
evt, evt,
sendTo, sendTo,
@@ -20,11 +20,11 @@ function assertTwilio(twilio: TwilioClient.Twilio | undefined): asserts twilio i
} }
function getDefaultSender(whatsapp = false) { function getDefaultSender(whatsapp = false) {
let defaultSender = process.env.TWILIO_PHONE_NUMBER let defaultSender = process.env.TWILIO_PHONE_NUMBER;
if (whatsapp) { if (whatsapp) {
defaultSender = `whatsapp:+${process.env.TWILIO_WHATSAPP_PHONE_NUMBER}` defaultSender = `whatsapp:+${process.env.TWILIO_WHATSAPP_PHONE_NUMBER}`;
} }
return defaultSender return defaultSender;
} }
function getSMSNumber(phone: string, whatsapp = false) { function getSMSNumber(phone: string, whatsapp = false) {
@@ -43,7 +43,13 @@ export const sendSMS = async (phoneNumber: string, body: string, sender: string,
return response; return response;
}; };
export const scheduleSMS = async (phoneNumber: string, body: string, scheduledDate: Date, sender: string, whatsapp = false) => { export const scheduleSMS = async (
phoneNumber: string,
body: string,
scheduledDate: Date,
sender: string,
whatsapp = false
) => {
assertTwilio(twilio); assertTwilio(twilio);
const response = await twilio.messages.create({ const response = await twilio.messages.create({
body: body, body: body,
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more