Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1566a80e40 | ||
|
|
797d3a7f98 | ||
|
|
c7a276eb1d | ||
|
|
1709e23135 | ||
|
|
d1778fdce8 | ||
|
|
b49952b8d8 | ||
|
|
5b280b2188 | ||
|
|
3818093652 | ||
|
|
56f4310c24 | ||
|
|
7ec7195ae9 | ||
|
|
514db3466f | ||
|
|
cd88b688f4 | ||
|
|
939a32813f | ||
|
|
66c1e29d91 | ||
|
|
3c57082fa6 | ||
|
|
fc4a2bd186 | ||
|
|
3f900966b0 | ||
|
|
8ba4b4d50e | ||
|
|
d2104dac5a | ||
|
|
9ad2731358 | ||
|
|
c34fdab5af | ||
|
|
f1c981fdcf | ||
|
|
47f65bb19f | ||
|
|
587d3c1088 | ||
|
|
610c86837a | ||
|
|
676452b4f4 | ||
|
|
8a432b45a4 | ||
|
|
92ad652666 | ||
|
|
617ddcaa3b | ||
|
|
ef7f3e7900 | ||
|
|
4e0a549a50 | ||
|
|
8f95d27469 | ||
|
|
8902f7efa1 | ||
|
|
bd7eadd721 | ||
|
|
02e34a7bde | ||
|
|
d51e1ab47d | ||
|
|
ebe60c36bd | ||
|
|
26e458be6d | ||
|
|
1ad4f7247e | ||
|
|
e0237acac9 | ||
|
|
2dc0bb4888 | ||
|
|
dfffd8b577 | ||
|
|
e6f2ba2c25 | ||
|
|
628a29e89c | ||
|
|
2fd9ef2733 | ||
|
|
c9f2d6bc93 | ||
|
|
a83aea30da | ||
|
|
b516a2af44 | ||
|
|
d0e831975d | ||
|
|
b906c7caf7 | ||
|
|
152dbe58c9 | ||
|
|
b4c154a6af | ||
|
|
99cea7a326 | ||
|
|
d0ae519851 | ||
|
|
d185c665b8 | ||
|
|
baa9ddf46a | ||
|
|
e8f5090acc | ||
|
|
0661b96cd2 | ||
|
|
3a64506c9e | ||
|
|
f1b705e022 | ||
|
|
c768d52539 | ||
|
|
7d3ba5c55c | ||
|
|
e643afaa80 | ||
|
|
4cd3479cfd | ||
|
|
7efddfd213 | ||
|
|
a8c362dbf3 | ||
|
|
f6b3cc0c7c | ||
|
|
902bb71273 | ||
|
|
db021cc696 | ||
|
|
a2645c2ed4 | ||
|
|
1ec9a6924c | ||
|
|
09068b39e6 | ||
|
|
9069a2412d | ||
|
|
6b5c8935c5 | ||
|
|
d27ff41682 | ||
|
|
c6ca736daa | ||
|
|
cedb2b72e9 | ||
|
|
11081cb5d8 | ||
|
|
34d65f67a9 | ||
|
|
e4c49d0e0b |
@@ -22,18 +22,18 @@ Any other relevant information. For example, why do you consider this a bug and
|
||||
|
||||
### 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
|
||||
|
||||
- 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
|
||||
|
||||
- Browser version, screen recording, console logs, network requests: You can make a recording with [Bird Eats Bug](https://birdeatsbug.com/).
|
||||
- Node.js version
|
||||
- Anything else that you think could be an issue.
|
||||
- Browser version, screen recording, console logs, network requests: You can make a recording with [Bird Eats Bug](https://birdeatsbug.com/).
|
||||
- Node.js version
|
||||
- Anything else that you think could be an issue.
|
||||
|
||||
### 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.
|
||||
|
||||
@@ -11,31 +11,32 @@ Fixes # (issue)
|
||||
## Requirement/Documentation
|
||||
|
||||
<!-- 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
|
||||
|
||||
<!-- Please delete bullets that are not relevant. -->
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] Chore (refactoring code, technical debt, workflow improvements)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] Chore (refactoring code, technical debt, workflow improvements)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
## 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 -->
|
||||
|
||||
- Are there environment variables that should be set?
|
||||
- What are the minimal test data to have?
|
||||
- What is expected (happy path) to have (input and output)?
|
||||
- Any other important info that could help to test that PR
|
||||
- Are there environment variables that should be set?
|
||||
- What are the minimal test data to have?
|
||||
- What is expected (happy path) to have (input and output)?
|
||||
- Any other important info that could help to test that PR
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
@@ -7,8 +7,13 @@ on:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
env:
|
||||
name: Create env file
|
||||
uses: ./.github/workflows/env-create-file.yml
|
||||
secrets: inherit
|
||||
build:
|
||||
name: Production build
|
||||
needs: env
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: ./.github/workflows/production-build.yml
|
||||
secrets: inherit
|
||||
|
||||
@@ -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)
|
||||
- [Daily.co](https://go.cal.com/daily)
|
||||
|
||||
|
||||
## Contact us
|
||||
|
||||
Meet our sales team for any commercial inquiries.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<a href="https://cal.com/docs/enterprise-features/api#api-server-specifications">Read the API docs</a>
|
||||
</div>
|
||||
|
||||
# Commercial Cal.com Public API
|
||||
# Commercial Cal.com Public API
|
||||
|
||||
Welcome to the Public API ("/apps/api") of the Cal.com.
|
||||
|
||||
|
||||
@@ -191,8 +191,8 @@ export default function MyApp() {
|
||||
${uiInstructionCode}
|
||||
})();
|
||||
}, [])
|
||||
return <Cal
|
||||
calLink="${calLink}"
|
||||
return <Cal
|
||||
calLink="${calLink}"
|
||||
style={{width:"${width}",height:"${height}",overflow:"scroll"}}
|
||||
${previewState.layout ? "config={{layout: '" + previewState.layout + "'}}" : ""}${
|
||||
IS_SELF_HOSTED
|
||||
@@ -243,11 +243,11 @@ export default function App() {
|
||||
${uiInstructionCode}
|
||||
})();
|
||||
}, [])
|
||||
return <button
|
||||
return <button
|
||||
data-cal-link="${calLink}"${IS_SELF_HOSTED ? `\ndata-cal-origin="${EMBED_CAL_ORIGIN}"` : ""}
|
||||
${`data-cal-config='${JSON.stringify({
|
||||
layout: previewState.layout,
|
||||
})}'`}
|
||||
})}'`}
|
||||
>Click me</button>;
|
||||
};`;
|
||||
},
|
||||
@@ -292,10 +292,10 @@ ${uiInstructionCode}`;
|
||||
}) => {
|
||||
return code`
|
||||
// Important: Please add following attributes to the element you want to open Cal on click
|
||||
// \`data-cal-link="${calLink}"\`
|
||||
// \`data-cal-link="${calLink}"\`
|
||||
// \`data-cal-config='${JSON.stringify({
|
||||
layout: previewState.layout,
|
||||
})}'\`
|
||||
})}'\`
|
||||
|
||||
${uiInstructionCode}`;
|
||||
},
|
||||
@@ -1182,7 +1182,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
</div>
|
||||
</div>
|
||||
<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) => {
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { isEmpty } from "lodash";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useEffect } from "react";
|
||||
|
||||
@@ -20,13 +19,13 @@ export function useViewerI18n() {
|
||||
/**
|
||||
* Auto-switches locale client-side to the logged in user's preference
|
||||
*/
|
||||
const I18nLanguageHandler = (): null => {
|
||||
const I18nLanguageHandler = () => {
|
||||
const { i18n } = useTranslation("common");
|
||||
const locale = useViewerI18n().data?.locale || i18n.language;
|
||||
|
||||
useEffect(() => {
|
||||
// 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 && i18n.language !== locale) {
|
||||
i18n.changeLanguage(locale);
|
||||
@@ -35,7 +34,6 @@ const I18nLanguageHandler = (): null => {
|
||||
document.dir = i18n.dir();
|
||||
document.documentElement.setAttribute("lang", locale);
|
||||
}, [locale, i18n]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { IframeHTMLAttributes } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
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 { InstallAppButton, AppDependencyComponent } from "@calcom/app-store/components";
|
||||
@@ -217,7 +217,7 @@ const Component = ({
|
||||
};
|
||||
}
|
||||
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} />
|
||||
);
|
||||
}}
|
||||
/>
|
||||
@@ -426,7 +426,7 @@ const InstallAppButtonChild = ({
|
||||
size="base">
|
||||
{multiInstall ? t("install_another") : t("install_app")}
|
||||
</Button>
|
||||
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -444,49 +444,50 @@ const InstallAppButtonChild = ({
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent
|
||||
onInteractOutside={(event) => {
|
||||
if (mutation.isLoading) event.preventDefault();
|
||||
}}
|
||||
onInteractOutside={(event) => {
|
||||
if (mutation.isLoading) event.preventDefault();
|
||||
}}
|
||||
>
|
||||
{mutation.isLoading && (
|
||||
<div className="z-1 fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
|
||||
<Spinner />
|
||||
</div>
|
||||
)}
|
||||
<div className="z-1 fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
|
||||
<Spinner />
|
||||
</div>
|
||||
)}
|
||||
<DropdownMenuLabel>{t("install_app_on")}</DropdownMenuLabel>
|
||||
{userAdminTeams.map((team) => {
|
||||
|
||||
|
||||
const isInstalled = credentials &&
|
||||
credentials.some((credential) =>
|
||||
credential?.teamId ? credential?.teamId === team.id : credential.userId === team.id
|
||||
)
|
||||
credentials.some((credential) =>
|
||||
credential?.teamId ? credential?.teamId === team.id : credential.userId === team.id
|
||||
)
|
||||
|
||||
return (
|
||||
<DropdownItem
|
||||
type="button"
|
||||
data-testid={team.isUser ? "install-app-button-personal" : "anything else"}
|
||||
key={team.id}
|
||||
disabled={
|
||||
isInstalled
|
||||
}
|
||||
StartIcon={(props) => (
|
||||
<Avatar
|
||||
alt={team.logo || ""}
|
||||
imageSrc={team.logo || `${CAL_URL}/${team.logo}/avatar.png`} // if no image, use default avatar
|
||||
size="sm"
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
onClick={() => {
|
||||
mutation.mutate(
|
||||
team.isUser ? addAppMutationInput : { ...addAppMutationInput, teamId: team.id }
|
||||
);
|
||||
}}>
|
||||
<p>{team.name}{" "}
|
||||
{isInstalled &&
|
||||
`(${t("installed")})`}</p>
|
||||
</DropdownItem>
|
||||
)})}
|
||||
<DropdownItem
|
||||
type="button"
|
||||
data-testid={team.isUser ? "install-app-button-personal" : "anything else"}
|
||||
key={team.id}
|
||||
disabled={
|
||||
isInstalled
|
||||
}
|
||||
StartIcon={(props) => (
|
||||
<Avatar
|
||||
alt={team.logo || ""}
|
||||
imageSrc={team.logo || `${CAL_URL}/${team.logo}/avatar.png`} // if no image, use default avatar
|
||||
size="sm"
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
onClick={() => {
|
||||
mutation.mutate(
|
||||
team.isUser ? addAppMutationInput : { ...addAppMutationInput, teamId: team.id }
|
||||
);
|
||||
}}>
|
||||
<p>{team.name}{" "}
|
||||
{isInstalled &&
|
||||
`(${t("installed")})`}</p>
|
||||
</DropdownItem>
|
||||
)
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</Dropdown>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import short from "short-uuid";
|
||||
import { v5 as uuidv5 } from "uuid";
|
||||
import { z } from "zod";
|
||||
import type { z } from "zod";
|
||||
|
||||
import type { EventNameObjectType } from "@calcom/core/event";
|
||||
import { getEventName } from "@calcom/core/event";
|
||||
@@ -17,14 +17,23 @@ import {
|
||||
allowDisablingHostConfirmationEmails,
|
||||
} from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails";
|
||||
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 { classNames } from "@calcom/lib";
|
||||
import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
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 RequiresConfirmationController from "./RequiresConfirmationController";
|
||||
@@ -87,7 +96,9 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
|
||||
return {
|
||||
...field,
|
||||
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;
|
||||
@@ -340,7 +351,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
|
||||
}}
|
||||
/>
|
||||
<div className="mt-2">
|
||||
<Checkbox
|
||||
<CheckboxField
|
||||
description={t("show_attendees")}
|
||||
disabled={seatsLocked.disabled}
|
||||
onChange={(e) => formMethods.setValue("seatsShowAttendees", e.target.checked)}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Trans } from "next-i18next";
|
||||
import Link from "next/link";
|
||||
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
|
||||
@@ -158,9 +160,21 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
|
||||
{!shouldLockDisableProps("apps").disabled && (
|
||||
<div className="bg-muted rounded-md p-8">
|
||||
{!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
|
||||
<Link className="cursor-pointer underline" href="/apps">
|
||||
App Store
|
||||
</Link>
|
||||
</Trans>
|
||||
</p>
|
||||
</>
|
||||
) : 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) => (
|
||||
<EventTypeAppCard
|
||||
getAppData={getAppDataGetter(app.slug as EventTypeAppsList)}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 type { OptionProps, SingleValueProps } from "react-select";
|
||||
import { components } from "react-select";
|
||||
@@ -71,86 +71,91 @@ const format = (date: Date, hour12: boolean) =>
|
||||
hourCycle: hour12 ? "h12" : "h24",
|
||||
}).format(new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss")));
|
||||
|
||||
const EventTypeScheduleDetails = ({
|
||||
isManagedEventType,
|
||||
selectedScheduleValue,
|
||||
}: {
|
||||
isManagedEventType: boolean;
|
||||
selectedScheduleValue: AvailabilityOption | undefined;
|
||||
}) => {
|
||||
const { data: loggedInUser } = useMeQuery();
|
||||
const timeFormat = loggedInUser?.timeFormat;
|
||||
const { t, i18n } = useLocale();
|
||||
const { watch } = useFormContext<FormValues>();
|
||||
const EventTypeScheduleDetails = memo(
|
||||
({
|
||||
isManagedEventType,
|
||||
selectedScheduleValue,
|
||||
}: {
|
||||
isManagedEventType: boolean;
|
||||
selectedScheduleValue: AvailabilityOption | undefined;
|
||||
}) => {
|
||||
const { data: loggedInUser } = useMeQuery();
|
||||
const timeFormat = loggedInUser?.timeFormat;
|
||||
const { t, i18n } = useLocale();
|
||||
const { watch } = useFormContext<FormValues>();
|
||||
|
||||
const scheduleId = watch("schedule");
|
||||
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
{
|
||||
scheduleId: scheduleId || loggedInUser?.defaultScheduleId || selectedScheduleValue?.value || undefined,
|
||||
isManagedEventType,
|
||||
},
|
||||
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId || !!selectedScheduleValue }
|
||||
);
|
||||
const scheduleId = watch("schedule");
|
||||
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
{
|
||||
scheduleId:
|
||||
scheduleId || loggedInUser?.defaultScheduleId || selectedScheduleValue?.value || undefined,
|
||||
isManagedEventType,
|
||||
},
|
||||
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId || !!selectedScheduleValue }
|
||||
);
|
||||
|
||||
const filterDays = (dayNum: number) =>
|
||||
schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
|
||||
const filterDays = (dayNum: number) =>
|
||||
schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
|
||||
|
||||
return (
|
||||
<div className="border-default space-y-4 rounded border px-6 pb-4">
|
||||
<ol className="table border-collapse text-sm">
|
||||
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
|
||||
const isAvailable = !!filterDays(index).length;
|
||||
return (
|
||||
<li key={day} className="my-6 flex border-transparent last:mb-2">
|
||||
<span
|
||||
className={classNames(
|
||||
"w-20 font-medium sm:w-32 ",
|
||||
!isAvailable ? "text-subtle line-through" : "text-default"
|
||||
)}>
|
||||
{day}
|
||||
</span>
|
||||
{isLoading ? (
|
||||
<SkeletonText className="block h-5 w-60" />
|
||||
) : isAvailable ? (
|
||||
<div className="space-y-3 text-right">
|
||||
{filterDays(index).map((dayRange, i) => (
|
||||
<div key={i} className="text-default flex items-center leading-4">
|
||||
<span className="w-16 sm:w-28 sm:text-left">
|
||||
{format(dayRange.startTime, timeFormat === 12)}
|
||||
</span>
|
||||
<span className="ms-4">-</span>
|
||||
<div className="ml-6 sm:w-28">{format(dayRange.endTime, timeFormat === 12)}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-subtle ml-6 sm:ml-0">{t("unavailable")}</span>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ol>
|
||||
<hr className="border-subtle" />
|
||||
<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">
|
||||
<Globe className="h-3.5 w-3.5 ltr:mr-2 rtl:ml-2" />
|
||||
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
|
||||
</span>
|
||||
{!!schedule?.id && !schedule.isManaged && (
|
||||
<Button
|
||||
href={`/availability/${schedule.id}`}
|
||||
disabled={isLoading}
|
||||
color="minimal"
|
||||
EndIcon={ExternalLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{t("edit_availability")}
|
||||
</Button>
|
||||
)}
|
||||
return (
|
||||
<div className="border-default space-y-4 rounded border px-6 pb-4">
|
||||
<ol className="table border-collapse text-sm">
|
||||
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
|
||||
const isAvailable = !!filterDays(index).length;
|
||||
return (
|
||||
<li key={day} className="my-6 flex border-transparent last:mb-2">
|
||||
<span
|
||||
className={classNames(
|
||||
"w-20 font-medium sm:w-32 ",
|
||||
!isAvailable ? "text-subtle line-through" : "text-default"
|
||||
)}>
|
||||
{day}
|
||||
</span>
|
||||
{isLoading ? (
|
||||
<SkeletonText className="block h-5 w-60" />
|
||||
) : isAvailable ? (
|
||||
<div className="space-y-3 text-right">
|
||||
{filterDays(index).map((dayRange, i) => (
|
||||
<div key={i} className="text-default flex items-center leading-4">
|
||||
<span className="w-16 sm:w-28 sm:text-left">
|
||||
{format(dayRange.startTime, timeFormat === 12)}
|
||||
</span>
|
||||
<span className="ms-4">-</span>
|
||||
<div className="ml-6 sm:w-28">{format(dayRange.endTime, timeFormat === 12)}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-subtle ml-6 sm:ml-0">{t("unavailable")}</span>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ol>
|
||||
<hr className="border-subtle" />
|
||||
<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">
|
||||
<Globe className="h-3.5 w-3.5 ltr:mr-2 rtl:ml-2" />
|
||||
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
|
||||
</span>
|
||||
{!!schedule?.id && !schedule.isManaged && (
|
||||
<Button
|
||||
href={`/availability/${schedule.id}`}
|
||||
disabled={isLoading}
|
||||
color="minimal"
|
||||
EndIcon={ExternalLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{t("edit_availability")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
EventTypeScheduleDetails.displayName = "EventTypeScheduleDetails";
|
||||
|
||||
const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
|
||||
const { t } = useLocale();
|
||||
|
||||
@@ -19,16 +19,17 @@ interface IUserToValue {
|
||||
email: string;
|
||||
}
|
||||
|
||||
const mapUserToValue = ({ id, name, username, email }: IUserToValue) => ({
|
||||
const mapUserToValue = ({ id, name, username, email }: IUserToValue, pendingString: string) => ({
|
||||
value: `${id || ""}`,
|
||||
label: `${name || ""}`,
|
||||
label: `${name || email || ""}${!username ? ` (${pendingString})` : ""}`,
|
||||
avatar: `${WEBAPP_URL}/${username}/avatar.png`,
|
||||
email,
|
||||
});
|
||||
|
||||
export const mapMemberToChildrenOption = (
|
||||
member: EventTypeSetupProps["teamMembers"][number],
|
||||
slug: string
|
||||
slug: string,
|
||||
pendingString: string
|
||||
) => {
|
||||
return {
|
||||
slug,
|
||||
@@ -43,7 +44,7 @@ export const mapMemberToChildrenOption = (
|
||||
eventTypeSlugs: member.eventTypes ?? [],
|
||||
},
|
||||
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"),
|
||||
},
|
||||
];
|
||||
const teamMembersOptions = teamMembers.map(mapUserToValue);
|
||||
const childrenEventTypeOptions = teamMembers.map((member) => {
|
||||
return mapMemberToChildrenOption(member, eventType.slug);
|
||||
const pendingMembers = (member: (typeof teamMembers)[number]) =>
|
||||
!!eventType.team?.parentId || !!member.username;
|
||||
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;
|
||||
return (
|
||||
|
||||
@@ -407,13 +407,13 @@ function EventTypeSingleLayout({
|
||||
className="primary-navigation"
|
||||
tabs={EventTypeTabs}
|
||||
sticky
|
||||
linkProps={{ shallow: true }}
|
||||
linkShallow
|
||||
itemClassname="items-start"
|
||||
iconClassName="md:mt-px"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-2 md:mx-0 md:p-0 xl:hidden">
|
||||
<HorizontalTabs tabs={EventTypeTabs} linkProps={{ shallow: true }} />
|
||||
<HorizontalTabs tabs={EventTypeTabs} linkShallow />
|
||||
</div>
|
||||
<div className="w-full ltr:mr-2 rtl:ml-2">
|
||||
<div
|
||||
|
||||
@@ -12,7 +12,7 @@ import TwoFactorAuthAPI from "./TwoFactorAuthAPI";
|
||||
interface DisableTwoFactorAuthModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: () => void;
|
||||
|
||||
disablePassword?: boolean;
|
||||
/** Called when the user closes the modal without disabling two-factor auth */
|
||||
onCancel: () => void;
|
||||
/** Called when the user disables two-factor auth */
|
||||
@@ -27,6 +27,7 @@ interface DisableTwoFactorValues {
|
||||
const DisableTwoFactorAuthModal = ({
|
||||
onDisable,
|
||||
onCancel,
|
||||
disablePassword,
|
||||
open,
|
||||
onOpenChange,
|
||||
}: DisableTwoFactorAuthModalProps) => {
|
||||
@@ -75,19 +76,21 @@ const DisableTwoFactorAuthModal = ({
|
||||
<DialogContent title={t("disable_2fa")} description={t("disable_2fa_recommendation")} type="creation">
|
||||
<Form form={form} handleSubmit={handleDisable}>
|
||||
<div className="mb-8">
|
||||
<PasswordField
|
||||
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"
|
||||
/>
|
||||
{!disablePassword && (
|
||||
<PasswordField
|
||||
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"
|
||||
/>
|
||||
)}
|
||||
<TwoFactor center={false} />
|
||||
|
||||
{errorMessage && <p className="mt-1 text-sm text-red-700">{errorMessage}</p>}
|
||||
</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}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -185,7 +185,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, open, onOpenChange }: Enable
|
||||
)}
|
||||
</div>
|
||||
</WithStep>
|
||||
<DialogFooter className="mt-8 sm:flex sm:flex-row-reverse" showDivider>
|
||||
<DialogFooter className="mt-8" showDivider>
|
||||
<Button color="secondary" onClick={onCancel}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -54,7 +54,12 @@ const getEmbedNamespace = (query: ReturnType<typeof useRouter>["query"]) => {
|
||||
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.
|
||||
* We intend to not cache i18n query
|
||||
@@ -222,11 +227,19 @@ const AppProviders = (props: AppPropsWithChildren) => {
|
||||
const session = trpc.viewer.public.session.useQuery().data;
|
||||
// No need to have intercom on public pages - Good for Page Performance
|
||||
const isPublicPage = usePublicPage();
|
||||
const { pageProps, ...rest } = props;
|
||||
const { _nonce, ...restPageProps } = pageProps;
|
||||
const propsWithoutNonce = {
|
||||
pageProps: {
|
||||
...restPageProps,
|
||||
},
|
||||
...rest,
|
||||
};
|
||||
|
||||
const RemainingProviders = (
|
||||
<EventCollectionProvider options={{ apiPath: "/api/collect-events" }}>
|
||||
<SessionProvider session={session || undefined}>
|
||||
<CustomI18nextProvider {...props}>
|
||||
<CustomI18nextProvider {...propsWithoutNonce}>
|
||||
<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 */}
|
||||
<CalcomThemeProvider
|
||||
|
||||
@@ -446,6 +446,27 @@ const nextConfig = {
|
||||
destination: "/apps/installed/conferencing",
|
||||
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") {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
|
||||
+4
-17
@@ -1,13 +1,14 @@
|
||||
import type { GetStaticPropsContext } from "next";
|
||||
import Link from "next/link";
|
||||
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 { DOCS_URL, JOIN_DISCORD, WEBSITE_URL, IS_CALCOM } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { HeadSeo } from "@calcom/ui";
|
||||
import { BookOpen, Check, ChevronRight, FileText, Shield } from "@calcom/ui/components/icon";
|
||||
import { Discord } from "@calcom/ui/components/icon/Discord";
|
||||
|
||||
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">
|
||||
<div className="flex-shrink-0">
|
||||
<span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg">
|
||||
<svg
|
||||
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>
|
||||
<Discord className="text-default h-6 w-6" />
|
||||
</span>
|
||||
</div>
|
||||
<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">
|
||||
<div className="flex-shrink-0">
|
||||
<span className="bg-muted flex h-12 w-12 items-center justify-center rounded-lg">
|
||||
<svg
|
||||
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>
|
||||
<Discord className="text-default h-6 w-6" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
|
||||
@@ -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
|
||||
const parsedUrl = new URL(asPath, "https://dummyurl");
|
||||
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);
|
||||
return { isEmbed, nonce, ...initialProps };
|
||||
return { isEmbed, embedColorScheme, nonce, ...initialProps };
|
||||
}
|
||||
|
||||
render() {
|
||||
const { locale } = this.props.__NEXT_DATA__;
|
||||
const { isEmbed } = this.props;
|
||||
const { isEmbed, embedColorScheme } = this.props;
|
||||
const nonceParsed = z.string().safeParse(this.props.nonce);
|
||||
const nonce = nonceParsed.success ? nonceParsed.data : "";
|
||||
return (
|
||||
<Html lang={locale}>
|
||||
<Html lang={locale} style={embedColorScheme ? { colorScheme: embedColorScheme as string } : undefined}>
|
||||
<Head nonce={nonce}>
|
||||
<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" />
|
||||
|
||||
@@ -12,7 +12,9 @@ import { IdentityProvider } from "@calcom/prisma/enums";
|
||||
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
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(),
|
||||
password: z.string().min(7),
|
||||
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 { symmetricDecrypt } from "@calcom/lib/crypto";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { IdentityProvider } from "@calcom/prisma/client";
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
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" });
|
||||
}
|
||||
|
||||
if (!user.password) {
|
||||
if (!user.password && user.identityProvider === IdentityProvider.CAL) {
|
||||
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" });
|
||||
}
|
||||
|
||||
const isCorrectPassword = await verifyPassword(req.body.password, user.password);
|
||||
if (!isCorrectPassword) {
|
||||
return res.status(400).json({ error: ErrorCode.IncorrectPassword });
|
||||
if (user.password && user.identityProvider === IdentityProvider.CAL) {
|
||||
const isCorrectPassword = await verifyPassword(req.body.password, user.password);
|
||||
if (!isCorrectPassword) {
|
||||
return res.status(400).json({ error: ErrorCode.IncorrectPassword });
|
||||
}
|
||||
}
|
||||
// if user has 2fa
|
||||
if (user.twoFactorEnabled) {
|
||||
|
||||
@@ -57,7 +57,7 @@ export default function Login({
|
||||
.string()
|
||||
.min(1, `${t("error_required_field")}`)
|
||||
.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();
|
||||
|
||||
@@ -279,7 +279,11 @@ export default function Availability() {
|
||||
</Dropdown>
|
||||
|
||||
<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")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -23,9 +23,9 @@ import {
|
||||
useIsEmbed,
|
||||
} from "@calcom/embed-core/embed-iframe";
|
||||
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 {
|
||||
SystemField,
|
||||
getBookingFieldsWithSystemFields,
|
||||
SMS_REMINDER_NUMBER_FIELD,
|
||||
} from "@calcom/features/bookings/lib/getBookingFields";
|
||||
|
||||
@@ -66,7 +66,6 @@ import {
|
||||
User as UserIcon,
|
||||
} from "@calcom/ui/components/icon";
|
||||
|
||||
import { withQuery } from "@lib/QueryCell";
|
||||
import useMeQuery from "@lib/hooks/useMeQuery";
|
||||
|
||||
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 { t } = useLocale();
|
||||
const router = useRouter();
|
||||
const { open } = useIntercom();
|
||||
const { query } = router;
|
||||
const { data: user } = useMeQuery();
|
||||
const isMobile = useMediaQuery("(max-width: 768px)");
|
||||
const [showProfileBanner, setShowProfileBanner] = useState(false);
|
||||
const orgBranding = useOrgBrandingValues();
|
||||
|
||||
@@ -860,10 +922,6 @@ const EventTypesPage = () => {
|
||||
);
|
||||
// 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 (
|
||||
<div>
|
||||
@@ -879,58 +937,7 @@ const EventTypesPage = () => {
|
||||
afterHeading={showProfileBanner && <SetupProfileBanner closeAction={closeBanner} />}
|
||||
beforeCTAactions={<Actions />}
|
||||
CTA={<CTA />}>
|
||||
<WithQuery
|
||||
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 />}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Main />
|
||||
</Shell>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -34,14 +34,15 @@ const TwoFactorAuthView = () => {
|
||||
if (isLoading) return <SkeletonLoader />;
|
||||
|
||||
const isCalProvider = user?.identityProvider === "CAL";
|
||||
const canSetupTwoFactor = !isCalProvider && !user?.twoFactorEnabled;
|
||||
return (
|
||||
<>
|
||||
<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">
|
||||
<Switch
|
||||
data-testid="two-factor-switch"
|
||||
disabled={!isCalProvider}
|
||||
disabled={canSetupTwoFactor}
|
||||
checked={user?.twoFactorEnabled}
|
||||
onCheckedChange={() =>
|
||||
user?.twoFactorEnabled ? setDisableModalOpen(true) : setEnableModalOpen(true)
|
||||
@@ -72,6 +73,7 @@ const TwoFactorAuthView = () => {
|
||||
|
||||
<DisableTwoFactorModal
|
||||
open={disableModalOpen}
|
||||
disablePassword={!isCalProvider}
|
||||
onOpenChange={() => setDisableModalOpen(!disableModalOpen)}
|
||||
onDisable={() => {
|
||||
setDisableModalOpen(false);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import { signIn } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
@@ -23,13 +24,18 @@ import PageWrapper from "@components/PageWrapper";
|
||||
import { IS_GOOGLE_LOGIN_ENABLED } from "../server/lib/constants";
|
||||
import { ssrInit } from "../server/lib/ssr";
|
||||
|
||||
type FormValues = {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
apiError: string;
|
||||
token?: string;
|
||||
};
|
||||
const signupSchema = z.object({
|
||||
username: z.string().refine((value) => !value.includes("+"), {
|
||||
message: "String should not contain a plus symbol (+).",
|
||||
}),
|
||||
email: z.string().email(),
|
||||
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>;
|
||||
|
||||
@@ -39,6 +45,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
|
||||
const flags = useFlagMap();
|
||||
const telemetry = useTelemetry();
|
||||
const methods = useForm<FormValues>({
|
||||
resolver: zodResolver(signupSchema),
|
||||
defaultValues: prepopulateFormValues,
|
||||
});
|
||||
const {
|
||||
|
||||
@@ -130,7 +130,9 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
|
||||
<div className="ms-3 inline-block truncate">
|
||||
<span className="text-default text-sm font-bold">{ch.name}</span>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,11 +140,13 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }
|
||||
className="mr-6"
|
||||
size="sm"
|
||||
truncateAfter={4}
|
||||
items={ch.members.map(({ user: member }) => ({
|
||||
alt: member.name || "",
|
||||
image: `/${member.username}/avatar.png`,
|
||||
title: member.name || "",
|
||||
}))}
|
||||
items={ch.members
|
||||
.filter((mem) => mem.user.username !== null)
|
||||
.map(({ user: member }) => ({
|
||||
alt: member.name || "",
|
||||
image: `/${member.username}/avatar.png`,
|
||||
title: member.name || "",
|
||||
}))}
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
@@ -36,7 +36,6 @@ test.describe("2FA Tests", async () => {
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
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 fillOtp({
|
||||
@@ -44,9 +43,9 @@ test.describe("2FA Tests", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
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;
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import { uuid } from "short-uuid";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
import { createHttpServer, waitFor, selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils";
|
||||
@@ -40,6 +41,101 @@ test.describe("Manage Booking Questions", () => {
|
||||
|
||||
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", () => {
|
||||
@@ -91,12 +187,23 @@ async function runTestStepsCommonForTeamAndUserEventType(
|
||||
}
|
||||
) {
|
||||
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 addQuestionAndSave({
|
||||
page,
|
||||
question: {
|
||||
name: "how_are_you",
|
||||
type: "Name",
|
||||
type: "Address",
|
||||
label: "How are you?",
|
||||
placeholder: "I'm fine, thanks",
|
||||
required: true,
|
||||
@@ -104,13 +211,13 @@ async function runTestStepsCommonForTeamAndUserEventType(
|
||||
});
|
||||
|
||||
await doOnFreshPreview(page, context, async (page) => {
|
||||
const allFieldsLocator = await expectSystemFieldsToBeThere(page);
|
||||
const allFieldsLocator = await expectSystemFieldsToBeThereOnBookingPage({ page });
|
||||
const userFieldLocator = allFieldsLocator.nth(5);
|
||||
|
||||
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
|
||||
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({
|
||||
name: "Booker",
|
||||
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 nameLocator = allFieldsLocator.nth(0);
|
||||
const emailLocator = allFieldsLocator.nth(1);
|
||||
@@ -226,11 +348,44 @@ async function expectSystemFieldsToBeThere(page: Page) {
|
||||
const additionalNotes = allFieldsLocator.nth(3);
|
||||
const guestsLocator = allFieldsLocator.nth(4);
|
||||
|
||||
await expect(nameLocator.locator('[name="name"]')).toBeVisible();
|
||||
await expect(emailLocator.locator('[name="email"]')).toBeVisible();
|
||||
if (isFirstAndLastNameVariant) {
|
||||
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();
|
||||
await expect(guestsLocator.locator("button")).toBeVisible();
|
||||
if (values?.email) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -238,11 +393,33 @@ async function expectSystemFieldsToBeThere(page: Page) {
|
||||
// Verify webhook is sent with the correct data, DB is correct (including metadata)
|
||||
|
||||
//TODO: Verify that prefill works
|
||||
async function bookTimeSlot({ page, name, email }: { page: Page; name: string; email: string }) {
|
||||
// --- fill form
|
||||
await page.fill('[name="name"]', name);
|
||||
await page.fill('[name="email"]', email);
|
||||
await page.press('[name="email"]', "Enter");
|
||||
async function bookTimeSlot({
|
||||
page,
|
||||
name,
|
||||
email,
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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.",
|
||||
"have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.",
|
||||
"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_cancelled_subject": "Zrušeno: {{title}} ({{date}})",
|
||||
"event_request_declined": "Žádost o 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",
|
||||
"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_placeholder": "Proč rušíte?\n",
|
||||
"rejection_reason": "Důvod odmítnutí",
|
||||
@@ -75,7 +87,9 @@
|
||||
"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_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_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}}",
|
||||
"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}}",
|
||||
@@ -104,6 +118,7 @@
|
||||
"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.",
|
||||
"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_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.",
|
||||
@@ -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.",
|
||||
"upgrade_banner_action": "Upgradovat zde",
|
||||
"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íž",
|
||||
"hey_there": "Zdravíme,",
|
||||
"forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}",
|
||||
@@ -180,6 +197,7 @@
|
||||
"blog": "Blog",
|
||||
"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_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",
|
||||
"popular_pages": "Oblíbené stránky",
|
||||
"register_now": "Zaregistrovat se nyní",
|
||||
@@ -187,6 +205,7 @@
|
||||
"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.",
|
||||
"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",
|
||||
"15min_meeting": "15 min schůzka",
|
||||
"30min_meeting": "30 min schůzka",
|
||||
@@ -222,11 +241,14 @@
|
||||
"done": "Hotovo",
|
||||
"all_done": "Hotovo!",
|
||||
"all": "Všechny aplikace",
|
||||
"yours": "Váš účet",
|
||||
"available_apps": "Dostupné aplikace",
|
||||
"check_email_reset_password": "Podívejte se do e-mailu. Poslali jsme vám odkaz pro obnovení hesla.",
|
||||
"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.",
|
||||
"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": "Nastavte, jak jste dostupní",
|
||||
"continue_without_calendar": "Pokračovat bez kalendáře",
|
||||
@@ -282,6 +304,18 @@
|
||||
"success": "Povedlo 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.",
|
||||
"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.",
|
||||
"sunday_time_error": "Neplatný čas v neděli",
|
||||
"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",
|
||||
"back_to_bookings": "Zpět na rezervace",
|
||||
"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ě",
|
||||
"really_cancel_booking": "Opravdu chcete zrušit svou rezervaci?",
|
||||
"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_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_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",
|
||||
"go_back_home": "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}}",
|
||||
"event_between_users": "{{eventName}} mezi {{host}} a {{attendeeName}}",
|
||||
"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.",
|
||||
"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.",
|
||||
"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_tooltip": "Nepotvrzené rezervace",
|
||||
"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",
|
||||
"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í",
|
||||
"dynamic_booking": "Dynamické odkazy na skupiny",
|
||||
"email": "E-mailová adresa",
|
||||
"email_placeholder": "vas@email.cz",
|
||||
"full_name": "Jméno a příjmení",
|
||||
"browse_api_documentation": "Procházejte naši API dokumentaci",
|
||||
"leverage_our_api": "Pro plnou kontrolu a přizpůsobení využijte naše API.",
|
||||
"create_webhook": "Vytvořit webhook",
|
||||
"booking_cancelled": "Rezervace zrušena",
|
||||
"booking_rescheduled": "Rezervace přesunuta",
|
||||
"recording_ready": "Odkaz ke stažení záznamu je připraven",
|
||||
"booking_created": "Rezervace vytvořena",
|
||||
"booking_rejected": "Rezervace zamítnuta",
|
||||
"booking_requested": "Rezervace vyžádána",
|
||||
"meeting_ended": "Schůzka skončila",
|
||||
"form_submitted": "Formulář byl odeslán",
|
||||
"event_triggers": "Eventy na základě akce",
|
||||
@@ -366,6 +413,8 @@
|
||||
"team_webhooks": "Týmové Webhooky",
|
||||
"create_new_webhook_to_account": "Vytvořit nový webhook pro váš účet",
|
||||
"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",
|
||||
"loading": "Načítám...",
|
||||
"deleting": "Odstraňování...",
|
||||
@@ -428,6 +477,7 @@
|
||||
"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",
|
||||
"incorrect_password": "Heslo není správné.",
|
||||
"incorrect_email_password": "E-mail nebo heslo jsou nesprávné.",
|
||||
"use_setting": "Použít nastavení",
|
||||
"am_pm": "am/pm",
|
||||
"time_options": "Nastavení času",
|
||||
@@ -455,6 +505,7 @@
|
||||
"additional_guests": "Přidat hosty",
|
||||
"your_name": "Vaše jméno",
|
||||
"your_full_name": "Vaše celé jméno",
|
||||
"no_name": "Žádné jméno",
|
||||
"email_address": "E-mailová adresa",
|
||||
"enter_valid_email": "Zadejte platný e-mail",
|
||||
"location": "Místo",
|
||||
@@ -498,10 +549,13 @@
|
||||
"your_team_updated_successfully": "Váš tým byl úspěšně aktualizován.",
|
||||
"about": "O aplikaci",
|
||||
"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é",
|
||||
"organization_members": "Členové organizace",
|
||||
"member": "Člen",
|
||||
"number_member_one": "Počet členů: {{count}}",
|
||||
"number_member_other": "Počet členů: {{count}}",
|
||||
"number_selected": "Vybráno: {{count}}",
|
||||
"owner": "Vlastník",
|
||||
"admin": "Administrátor",
|
||||
"administrator_user": "Uživatel administrátor",
|
||||
@@ -532,6 +586,8 @@
|
||||
"confirm_all": "Potvrdit vše",
|
||||
"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_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?",
|
||||
"confirm_disband_team": "Ano, rozpustit tým",
|
||||
"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_deleted_successfully": "Typ události byl úspěšně smazán",
|
||||
"hours": "Hodiny",
|
||||
"people": "Lidé",
|
||||
"your_email": "Váš e-mail",
|
||||
"change_avatar": "Změnit avatar",
|
||||
"language": "Jazyk",
|
||||
@@ -638,9 +695,11 @@
|
||||
"create_new_team": "Vytvořit nový tým",
|
||||
"open_invitations": "Otevřené pozvánky",
|
||||
"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",
|
||||
"teams": "Týmy",
|
||||
"team": "Tým",
|
||||
"organization": "Organizace",
|
||||
"team_billing": "Fakturace 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",
|
||||
@@ -715,6 +774,7 @@
|
||||
"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",
|
||||
"require_payment": "Vyžadovat platbu",
|
||||
"you_need_to_add_a_name": "Musíte přidat název",
|
||||
"commission_per_transaction": "provize za transakci",
|
||||
"event_type_updated_successfully_description": "Typ události byl úspěšně aktualizován.",
|
||||
"hide_event_type": "Skrýt typ události",
|
||||
@@ -805,18 +865,25 @@
|
||||
"installed_apps": "Nainstalované aplikace",
|
||||
"free_to_use_apps": "Zdarma",
|
||||
"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_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_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_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_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_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_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_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",
|
||||
"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í.",
|
||||
@@ -842,6 +909,7 @@
|
||||
"create_events_on": "Vytvořit události v:",
|
||||
"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_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",
|
||||
"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ů.",
|
||||
@@ -911,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Odvolat tento klíč API",
|
||||
"revoke_api_key": "Odvolat klíč API",
|
||||
"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?",
|
||||
"copy": "Kopírovat",
|
||||
"expire_date": "Datum uplynutí platnosti",
|
||||
@@ -933,6 +1002,9 @@
|
||||
"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.",
|
||||
"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í",
|
||||
"impersonate_user_tip": "Všechna použití této funkce jsou kontrolována.",
|
||||
"impersonating_user_warning": "Zosobnění uživatelského jména „{{user}}“.",
|
||||
@@ -1000,16 +1072,21 @@
|
||||
"event_location": "Místo události",
|
||||
"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",
|
||||
"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.",
|
||||
"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",
|
||||
"url_start_with_https": "Adresa URL musí začínat http:// nebo https://",
|
||||
"number_provided": "Bude uvedeno telefonní číslo",
|
||||
"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",
|
||||
"email_host_action": "odeslání e-mailu hostiteli",
|
||||
"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",
|
||||
"whatsapp_number_action": "odeslat Whatsapp na konkrétní číslo",
|
||||
"whatsapp_attendee_action": "odeslat Whatsapp účastníkovi",
|
||||
"workflows": "Pracovní postupy",
|
||||
"new_workflow_btn": "Nový pracovní postup",
|
||||
"add_new_workflow": "Přidat nový pracovní postup",
|
||||
@@ -1073,6 +1150,8 @@
|
||||
"choose_template": "Vyberte si šablonu",
|
||||
"custom": "Vlastní",
|
||||
"reminder": "Upomínka",
|
||||
"rescheduled": "Změna termínu",
|
||||
"completed": "Dokončeno",
|
||||
"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.",
|
||||
"minute_one": "{{count}} min",
|
||||
@@ -1170,6 +1249,7 @@
|
||||
"start_of_week": "Začátek týdne",
|
||||
"recordings_title": "Nahrávky",
|
||||
"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í.",
|
||||
"check_for_conflicts": "Zkontrolovat konflikty",
|
||||
"view_recordings": "Zobrazit nahrávky",
|
||||
@@ -1211,6 +1291,7 @@
|
||||
"conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky",
|
||||
"add_conferencing_app": "Přidat videokonferenční aplikaci",
|
||||
"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í.",
|
||||
"skip": "Přeskočit",
|
||||
"do_this_later": "Provést později",
|
||||
@@ -1224,6 +1305,8 @@
|
||||
"connect_analytics_apps": "Připojit analytické aplikace",
|
||||
"connect_other_apps": "Propojit další aplikace",
|
||||
"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}}",
|
||||
"add_variable": "Přidat proměnnou",
|
||||
"custom_phone_number": "Vlastní telefonní číslo",
|
||||
@@ -1236,12 +1319,14 @@
|
||||
"location_info": "Místo události",
|
||||
"additional_notes_info": "Další poznámky k rezervaci",
|
||||
"attendee_name_info": "Jméno osoby provádějící rezervaci",
|
||||
"organizer_name_info": "Jméno organizátora",
|
||||
"to": "Komu",
|
||||
"workflow_turned_on_successfully": "Pracovní postup {{workflowName}} byl {{offOn}}",
|
||||
"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": "Stáhnout",
|
||||
"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_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",
|
||||
@@ -1250,7 +1335,9 @@
|
||||
"event_one": "událost",
|
||||
"event_other": "událostí",
|
||||
"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ě",
|
||||
"organization_description": "Správa správců a členů vaší organizace",
|
||||
"team_url": "Adresa URL týmu",
|
||||
"team_members": "Členové týmu",
|
||||
"more": "Více",
|
||||
@@ -1291,6 +1378,7 @@
|
||||
"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",
|
||||
"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í",
|
||||
"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ě",
|
||||
@@ -1376,6 +1464,7 @@
|
||||
"new_event_type_availability": "Dostupnost pro {{eventTypeTitle}}",
|
||||
"error_editing_availability": "Chyba při úpravě dostupnosti",
|
||||
"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_email_required": "Zadejte prosím e-mail, abychom mohli určit vašeho SAML Identity Providera",
|
||||
"saml_sp_title": "Podrobnosti poskytovatele služby",
|
||||
@@ -1394,15 +1483,19 @@
|
||||
"yearly": "Ročně",
|
||||
"checkout": "Platba",
|
||||
"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",
|
||||
"you": "Vy",
|
||||
"resend_email": "Znovu odeslat e-mail",
|
||||
"member_already_invited": "Člen byl už pozván",
|
||||
"enter_email_or_username": "Zadejte e-mail nebo uživatelské jméno",
|
||||
"team_name_taken": "Toto jméno je už obsazeno",
|
||||
"must_enter_team_name": "Musíte zadat název týmu",
|
||||
"team_url_required": "Musíte zadat adresu URL týmu",
|
||||
"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",
|
||||
"number_text_notifications": "Telefonní číslo (SMS oznámení)",
|
||||
"attendee_email_variable": "E-mail účastníka",
|
||||
"attendee_email_info": "E-mail osoby provádějící rezervaci",
|
||||
"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.",
|
||||
"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ů.",
|
||||
"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“.",
|
||||
"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",
|
||||
@@ -1443,6 +1538,7 @@
|
||||
"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.",
|
||||
"enable_apps": "Povolit aplikace",
|
||||
"enable_apps_description": "Zapněte aplikace, které mohou uživatelé integrovat s aplikací {{appName}}",
|
||||
"purchase_license": "Kupte si licenci",
|
||||
"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.",
|
||||
@@ -1456,6 +1552,9 @@
|
||||
"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_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í",
|
||||
"fill_this_field": "Vyplňte prosím toto pole",
|
||||
"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.",
|
||||
"organizer_timezone": "Časové pásmo organizátora",
|
||||
"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_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_two": "Připojte svůj účet kalendáře",
|
||||
"email_no_user_step_three": "Nastavte si dostupnost",
|
||||
@@ -1570,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "Žádné 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",
|
||||
"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.",
|
||||
@@ -1580,7 +1684,9 @@
|
||||
"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": "Úč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_routing_form_on": "Vytvoření směrovacího formuláře v",
|
||||
"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.",
|
||||
"organizer_default_conferencing_app": "Výchozí aplikace organizátora",
|
||||
@@ -1590,6 +1696,7 @@
|
||||
"booking_questions_title": "Otázky k rezervaci",
|
||||
"booking_questions_description": "Přizpůsobte otázky položené na stránce rezervace",
|
||||
"add_a_booking_question": "Přidat otázku",
|
||||
"identifier": "Identifikátor",
|
||||
"duplicate_email": "Duplicitní e-mail",
|
||||
"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ě.",
|
||||
@@ -1600,6 +1707,7 @@
|
||||
"show_on_booking_page": "Zobrazit na stránce rezervace",
|
||||
"get_started_zapier_templates": "Začněte používat šablony Zapier",
|
||||
"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",
|
||||
"a_routing_form": "Směrovací formulář",
|
||||
"form_description_placeholder": "Popis formuláře",
|
||||
@@ -1629,13 +1737,16 @@
|
||||
"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í",
|
||||
"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",
|
||||
"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_description": "Vyberte časový slot, aby mohla být událost zaregistrována.",
|
||||
"timeslot_missing_cta": "Vybrat časový slot",
|
||||
"switch_monthly": "Přepnout na měsíční zobrazení",
|
||||
"switch_weekly": "Přepnout na tý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}}",
|
||||
"select_on_next_step": "Vyberte v dalším kroku",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Revidovat typ události",
|
||||
"looking_for_more_analytics": "Hledáte další analytické informace?",
|
||||
@@ -1689,12 +1801,14 @@
|
||||
"least_booked_members": "Nejméně rezervovaných členů",
|
||||
"events_created": "Události vytvořeny",
|
||||
"events_completed": "Události dokončeny",
|
||||
"events_cancelled": "Události zrušeny",
|
||||
"events_rescheduled": "Události přesunuty",
|
||||
"from_last_period": "z posledního období",
|
||||
"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“.",
|
||||
"event_trends": "Trendy událostí",
|
||||
"clear_filters": "Vymazat filtry",
|
||||
"clear": "Vymazat",
|
||||
"hold": "Blokace",
|
||||
"on_booking_option": "Vybrat platbu při rezervaci",
|
||||
"hold_option": "Účtovat poplatek za nedostavení se",
|
||||
@@ -1721,6 +1835,18 @@
|
||||
"complete_your_booking": "Dokončete svou rezervaci",
|
||||
"complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}",
|
||||
"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}}",
|
||||
"charge_card_dialog_body": "Chystáte se účtovat účastníkovi {{amount, currency}}. Opravdu chcete pokračovat?",
|
||||
"charge_attendee": "Naúčtovat účastníkovi {{amount, currency}}",
|
||||
@@ -1729,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "Počet pozvaných uživatelů: {{userCount}}",
|
||||
"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",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}: Nejste oprávněni zapnout nebo vypnout tento pracovní postup.",
|
||||
"inline_embed": "Vložit na řádek",
|
||||
"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",
|
||||
@@ -1748,6 +1875,69 @@
|
||||
"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",
|
||||
"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",
|
||||
"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_email_header": "Bestätigen Sie Ihre E-Mail-Adresse",
|
||||
"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_link_text": "Hier ist der Link, falls Sie lieber keine Schaltflächen anklicken möchten:",
|
||||
"email_sent": "E-Mail erfolgreich gesendet",
|
||||
@@ -84,7 +85,7 @@
|
||||
"booking_submitted_subject": "Buchung eingereicht: {{title}} am {{date}}",
|
||||
"download_recording_subject": "Aufnahme herunterladen: {{title}} am {{date}}",
|
||||
"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_has_been_rescheduled": "Ihr Termin wurde verschoben.",
|
||||
"request_reschedule_subtitle": "{{organizer}} hat die Buchung storniert und Sie gebeten, eine andere Zeit auszuwählen.",
|
||||
@@ -243,6 +244,8 @@
|
||||
"all": "Alle Apps",
|
||||
"yours": "Ihr Konto",
|
||||
"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.",
|
||||
"finish": "Fertig",
|
||||
"organization_general_description": "Einstellungen für die Sprache und Zeitzone Ihres Teams verwalten",
|
||||
@@ -406,6 +409,7 @@
|
||||
"booking_requested": "Buchung angefragt",
|
||||
"meeting_ended": "Meeting beendet",
|
||||
"form_submitted": "Formular gesendet",
|
||||
"booking_paid": "Buchung bezahlt",
|
||||
"event_triggers": "Event-Auslöser",
|
||||
"subscriber_url": "Subscriber-URL",
|
||||
"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.",
|
||||
"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",
|
||||
"first_name": "Vorname",
|
||||
"last_name": "Nachname",
|
||||
"first_last_name": "Vorname, Nachname",
|
||||
"invite_as": "Einladen als",
|
||||
"form_updated_successfully": "Formular erfolgreich aktualisiert.",
|
||||
"disable_attendees_confirmation_emails": "Standardmäßige Bestätigungs-E-Mails für Teilnehmer deaktivieren",
|
||||
@@ -1939,5 +1946,6 @@
|
||||
"insights_user_filter": "Benutzer: {{userName}}",
|
||||
"insights_subtitle": "Sehen Sie sich Buchungs-Insights über Ihre Termine an",
|
||||
"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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -244,6 +244,8 @@
|
||||
"all": "All",
|
||||
"yours": "Your account",
|
||||
"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.",
|
||||
"finish": "Finish",
|
||||
"organization_general_description": "Manage settings for your team language and timezone",
|
||||
@@ -407,6 +409,7 @@
|
||||
"booking_requested": "Booking Requested",
|
||||
"meeting_ended": "Meeting Ended",
|
||||
"form_submitted": "Form Submitted",
|
||||
"booking_paid": "Booking Paid",
|
||||
"event_triggers": "Event Triggers",
|
||||
"subscriber_url": "Subscriber URL",
|
||||
"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.",
|
||||
"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",
|
||||
"first_name": "First name",
|
||||
"last_name": "Last name",
|
||||
"first_last_name": "First name, Last name",
|
||||
"invite_as": "Invite as",
|
||||
"form_updated_successfully": "Form updated successfully.",
|
||||
"disable_attendees_confirmation_emails": "Disable default confirmation emails for attendees",
|
||||
|
||||
@@ -129,6 +129,8 @@
|
||||
"team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.",
|
||||
"upgrade_banner_action": "Actualizar aquí",
|
||||
"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",
|
||||
"hey_there": "Hola,",
|
||||
"forgot_your_password_calcom": "¿Olvidaste tu contraseña? - {{appName}}",
|
||||
@@ -195,6 +197,7 @@
|
||||
"blog": "Blog",
|
||||
"blog_description": "Lee nuestras últimas noticias y artículos",
|
||||
"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",
|
||||
"popular_pages": "Páginas Populares",
|
||||
"register_now": "Regístrate Ahora",
|
||||
@@ -202,6 +205,7 @@
|
||||
"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.",
|
||||
"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",
|
||||
"15min_meeting": "Reunión de 15 min",
|
||||
"30min_meeting": "Reunión de 30 min",
|
||||
@@ -237,11 +241,14 @@
|
||||
"done": "Hecho",
|
||||
"all_done": "¡Todo listo!",
|
||||
"all": "Todas las aplicaciones",
|
||||
"yours": "Su cuenta",
|
||||
"available_apps": "Aplicaciones disponibles",
|
||||
"check_email_reset_password": "Revisa tu email. Te hemos enviado un enlace para restablecer tu contraseña.",
|
||||
"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.",
|
||||
"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": "Establecer Disponibilidad",
|
||||
"continue_without_calendar": "Continuar sin calendario",
|
||||
@@ -297,6 +304,18 @@
|
||||
"success": "Éxito",
|
||||
"failed": "Falló",
|
||||
"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.",
|
||||
"sunday_time_error": "Hora inválida del domingo",
|
||||
"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",
|
||||
"back_to_bookings": "Volver a Reservas",
|
||||
"free_to_pick_another_event_type": "No dude en elegir otro evento en cualquier momento.",
|
||||
"cancelled": "Cancelado",
|
||||
"cancellation_successful": "Cancelación Realizada",
|
||||
"really_cancel_booking": "¿Realmente deseas cancelar tu 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_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_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ó",
|
||||
"go_back_home": "Volver a Inicio",
|
||||
"or_go_back_home": "O Volver al Inicio",
|
||||
@@ -326,10 +352,12 @@
|
||||
"no_status_bookings_yet_description": "No tienes {{status}} reservas. {{description}}",
|
||||
"event_between_users": "{{eventName}} entre {{host}} y {{attendeeName}}",
|
||||
"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.",
|
||||
"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í.",
|
||||
"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_tooltip": "Reservas sin confirmar",
|
||||
"on": "en",
|
||||
@@ -363,15 +391,19 @@
|
||||
"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": "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_placeholder": "nombre@ejemplo.com",
|
||||
"full_name": "Nombre Completo",
|
||||
"browse_api_documentation": "Consulte la documentación de nuestra API",
|
||||
"leverage_our_api": "Aproveche nuestra API para un control total y personalización.",
|
||||
"create_webhook": "Crear Webhook",
|
||||
"booking_cancelled": "Reserva cancelada",
|
||||
"booking_rescheduled": "Reserva habilitada",
|
||||
"recording_ready": "Enlace de descarga de grabación listo",
|
||||
"booking_created": "Reserva Creada",
|
||||
"booking_rejected": "Reserva rechazada",
|
||||
"booking_requested": "Reserva solicitada",
|
||||
"meeting_ended": "Reunión finalizada",
|
||||
"form_submitted": "Formulario enviado",
|
||||
"event_triggers": "Activadores de Eventos",
|
||||
@@ -381,6 +413,8 @@
|
||||
"team_webhooks": "Webhooks del equipo",
|
||||
"create_new_webhook_to_account": "Crear un nuevo webhook en tu cuenta",
|
||||
"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",
|
||||
"loading": "Cargando...",
|
||||
"deleting": "Eliminando...",
|
||||
@@ -443,6 +477,7 @@
|
||||
"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",
|
||||
"incorrect_password": "La Contraseña es Incorrecta.",
|
||||
"incorrect_email_password": "El correo electrónico o la contraseña son incorrectos.",
|
||||
"use_setting": "Usar Ajuste",
|
||||
"am_pm": "am/pm",
|
||||
"time_options": "Opciones Horas",
|
||||
@@ -470,6 +505,7 @@
|
||||
"additional_guests": "Añadir invitados",
|
||||
"your_name": "Tu Nombre",
|
||||
"your_full_name": "Su nombre completo",
|
||||
"no_name": "Sin nombre",
|
||||
"email_address": "Email",
|
||||
"enter_valid_email": "Ingresa un correo electrónico válido",
|
||||
"location": "Ubicación",
|
||||
@@ -513,10 +549,13 @@
|
||||
"your_team_updated_successfully": "Tu equipo ha sido actualizado con éxito.",
|
||||
"about": "Acerca de",
|
||||
"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",
|
||||
"organization_members": "Miembros de la organización",
|
||||
"member": "Miembro",
|
||||
"number_member_one": "{{count}} miembro",
|
||||
"number_member_other": "{{count}} miembros",
|
||||
"number_selected": "{{count}} seleccionados",
|
||||
"owner": "Propietario",
|
||||
"admin": "Administrador",
|
||||
"administrator_user": "Usuario administrador",
|
||||
@@ -547,6 +586,8 @@
|
||||
"confirm_all": "Confirmar todo",
|
||||
"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_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?",
|
||||
"confirm_disband_team": "Sí, Disolver Equipo",
|
||||
"confirm_remove_member": "Sí, Eliminar Miembro",
|
||||
@@ -621,6 +662,7 @@
|
||||
"event_type_updated_successfully": "{{eventTypeTitle}} tipo de evento actualizado con éxito",
|
||||
"event_type_deleted_successfully": "Tipo de evento eliminado con éxito",
|
||||
"hours": "Horas",
|
||||
"people": "Personas",
|
||||
"your_email": "Tu Email",
|
||||
"change_avatar": "Cambiar Avatar",
|
||||
"language": "Lenguaje",
|
||||
@@ -653,9 +695,11 @@
|
||||
"create_new_team": "Crear Nuevo Equipo",
|
||||
"open_invitations": "Invitaciones Abiertas",
|
||||
"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",
|
||||
"teams": "Equipos",
|
||||
"team": "Equipo",
|
||||
"organization": "Organización",
|
||||
"team_billing": "Facturación del equipo",
|
||||
"team_billing_description": "Gestione la facturación para su equipo",
|
||||
"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_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",
|
||||
"you_need_to_add_a_name": "Necesita agregar un nombre",
|
||||
"commission_per_transaction": "Comisión por Transacción",
|
||||
"event_type_updated_successfully_description": "Tu Evento fue Actualizado con Éxito.",
|
||||
"hide_event_type": "Ocultar Tipo de Evento",
|
||||
@@ -820,18 +865,25 @@
|
||||
"installed_apps": "Aplicaciones instaladas",
|
||||
"free_to_use_apps": "Gratis",
|
||||
"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_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_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_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_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_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_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_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",
|
||||
"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.",
|
||||
@@ -857,6 +909,7 @@
|
||||
"create_events_on": "Crear eventos en",
|
||||
"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_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",
|
||||
"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.",
|
||||
@@ -926,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Revocar esta clave API",
|
||||
"revoke_api_key": "Revocar clave API",
|
||||
"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?",
|
||||
"copy": "Copiar",
|
||||
"expire_date": "Fecha de caducidad",
|
||||
@@ -948,6 +1002,9 @@
|
||||
"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.",
|
||||
"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",
|
||||
"impersonate_user_tip": "Todos los usos de esta función son revisados.",
|
||||
"impersonating_user_warning": "Suplantando nombre de usuario \"{{user}}\".",
|
||||
@@ -1015,16 +1072,21 @@
|
||||
"event_location": "Ubicación del evento",
|
||||
"reschedule_optional": "Razón para reagendar (opcional)",
|
||||
"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.",
|
||||
"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",
|
||||
"url_start_with_https": "La URL debe empezar por http:// o https://",
|
||||
"number_provided": "Se proporcionará el número de teléfono",
|
||||
"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",
|
||||
"email_host_action": "enviar correo electrónico al anfitrión",
|
||||
"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",
|
||||
"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",
|
||||
"new_workflow_btn": "Flujo de trabajo nuevo",
|
||||
"add_new_workflow": "Agregar un flujo de trabajo nuevo",
|
||||
@@ -1088,6 +1150,8 @@
|
||||
"choose_template": "Elija una plantilla",
|
||||
"custom": "Personalizado",
|
||||
"reminder": "Recordatorio",
|
||||
"rescheduled": "Reprogramado",
|
||||
"completed": "Completado",
|
||||
"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.",
|
||||
"minute_one": "{{count}} minuto",
|
||||
@@ -1185,6 +1249,7 @@
|
||||
"start_of_week": "Inicio de la semana",
|
||||
"recordings_title": "Grabaciones",
|
||||
"recording": "Grabación",
|
||||
"happy_scheduling": "Feliz programación",
|
||||
"select_calendars": "Seleccione los calendarios en los que desee comprobar conflictos para evitar reservas dobles.",
|
||||
"check_for_conflicts": "Comprobar conflictos",
|
||||
"view_recordings": "Ver grabaciones",
|
||||
@@ -1226,6 +1291,7 @@
|
||||
"conferencing_description": "Añada sus aplicaciones de videoconferencia favoritas para sus reuniones",
|
||||
"add_conferencing_app": "Añadir aplicación de conferencia",
|
||||
"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.",
|
||||
"skip": "Omitir",
|
||||
"do_this_later": "Hacerlo más tarde",
|
||||
@@ -1239,6 +1305,8 @@
|
||||
"connect_analytics_apps": "Conecte aplicaciones de análisis",
|
||||
"connect_other_apps": "Conectar otras aplicaciones",
|
||||
"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}}",
|
||||
"add_variable": "Añadir variable",
|
||||
"custom_phone_number": "Número de teléfono personalizado",
|
||||
@@ -1251,12 +1319,14 @@
|
||||
"location_info": "Ubicación del evento",
|
||||
"additional_notes_info": "Notas adicionales de la reserva",
|
||||
"attendee_name_info": "Nombre de la persona que reserva",
|
||||
"organizer_name_info": "Nombre del organizador",
|
||||
"to": "Para",
|
||||
"workflow_turned_on_successfully": "El flujo de trabajo {{workflowName}} se ha activado {{offOn}} con éxito",
|
||||
"download_responses": "Descargar respuestas",
|
||||
"download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.",
|
||||
"download": "Descargar",
|
||||
"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_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",
|
||||
@@ -1265,7 +1335,9 @@
|
||||
"event_one": "evento",
|
||||
"event_other": "eventos",
|
||||
"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",
|
||||
"organization_description": "Gestione los administradores y miembros de su organización",
|
||||
"team_url": "URL del equipo",
|
||||
"team_members": "Miembros del equipo",
|
||||
"more": "Más",
|
||||
@@ -1306,6 +1378,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1391,6 +1464,7 @@
|
||||
"new_event_type_availability": "Disponibilidad para {{eventTypeTitle}}",
|
||||
"error_editing_availability": "Error al editar la disponibilidad",
|
||||
"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_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",
|
||||
@@ -1409,15 +1483,19 @@
|
||||
"yearly": "Anual",
|
||||
"checkout": "Proceder al pago",
|
||||
"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",
|
||||
"you": "Usted",
|
||||
"resend_email": "Reenviar correo electrónico",
|
||||
"member_already_invited": "El miembro ya se ha invitado",
|
||||
"enter_email_or_username": "Introduzca un correo electrónico o nombre de usuario",
|
||||
"team_name_taken": "Este nombre ya está en uso",
|
||||
"must_enter_team_name": "Debe introducir un nombre de equipo",
|
||||
"team_url_required": "Debe introducir una URL del equipo",
|
||||
"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",
|
||||
"number_text_notifications": "Número de teléfono (Notificaciones de texto)",
|
||||
"attendee_email_variable": "Correo electrónico del asistente",
|
||||
"attendee_email_info": "El correo electrónico de la persona que reserva",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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",
|
||||
@@ -1458,6 +1538,7 @@
|
||||
"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.",
|
||||
"enable_apps": "Activar aplicaciones",
|
||||
"enable_apps_description": "Habilite las aplicaciones que los usuarios pueden integrar con {{appName}}",
|
||||
"purchase_license": "Compre una licencia",
|
||||
"already_have_key": "Ya tengo una clave:",
|
||||
"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_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_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",
|
||||
"fill_this_field": "Complete este campo",
|
||||
"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.",
|
||||
"organizer_timezone": "Zona horaria del organizador",
|
||||
"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_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_two": "Conecte su cuenta de calendario",
|
||||
"email_no_user_step_three": "Establezca su disponibilidad",
|
||||
@@ -1585,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "No hay flujos de trabajo",
|
||||
"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",
|
||||
"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.",
|
||||
@@ -1595,7 +1684,9 @@
|
||||
"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": "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_routing_form_on": "Crear formulario de enrutamiento el",
|
||||
"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.",
|
||||
"organizer_default_conferencing_app": "Aplicación por defecto del organizador",
|
||||
@@ -1605,6 +1696,7 @@
|
||||
"booking_questions_title": "Preguntas sobre la reserva",
|
||||
"booking_questions_description": "Personalice las preguntas que se hacen en la página de reservas",
|
||||
"add_a_booking_question": "Agregar una pregunta",
|
||||
"identifier": "Identificador",
|
||||
"duplicate_email": "El correo electrónico está duplicado",
|
||||
"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.",
|
||||
@@ -1615,6 +1707,7 @@
|
||||
"show_on_booking_page": "Mostrar en la página de reserva",
|
||||
"get_started_zapier_templates": "Comience con las plantillas de Zapier",
|
||||
"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",
|
||||
"a_routing_form": "Un formulario de enrutamiento",
|
||||
"form_description_placeholder": "Descripción del formulario",
|
||||
@@ -1644,13 +1737,16 @@
|
||||
"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",
|
||||
"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",
|
||||
"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_description": "Seleccione un intervalo de tiempo para reservar el evento.",
|
||||
"timeslot_missing_cta": "Seleccionar intervalo de tiempo",
|
||||
"switch_monthly": "Cambiar a la vista mensual",
|
||||
"switch_weekly": "Cambiar a la vista semanal",
|
||||
"switch_multiday": "Cambiar a la vista diaria",
|
||||
"switch_columnview": "Cambiar a la vista de columna",
|
||||
"num_locations": "{{num}} opciones de ubicación",
|
||||
"select_on_next_step": "Seleccionar en el siguiente paso",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Revisar tipo de evento",
|
||||
"looking_for_more_analytics": "¿Busca más datos de análisis?",
|
||||
@@ -1704,12 +1801,14 @@
|
||||
"least_booked_members": "Miembros con menos reservas",
|
||||
"events_created": "Eventos creados",
|
||||
"events_completed": "Eventos completados",
|
||||
"events_cancelled": "Eventos cancelados",
|
||||
"events_rescheduled": "Eventos reprogramados",
|
||||
"from_last_period": "desde el último período",
|
||||
"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.",
|
||||
"event_trends": "Tendencias del evento",
|
||||
"clear_filters": "Eliminar filtros",
|
||||
"clear": "Borrar",
|
||||
"hold": "Retener",
|
||||
"on_booking_option": "Cobrar el pago durante la reserva",
|
||||
"hold_option": "Cobrar comisión por no presentarse",
|
||||
@@ -1736,6 +1835,18 @@
|
||||
"complete_your_booking": "Complete su reserva",
|
||||
"complete_your_booking_subject": "Complete su reserva: {{title}} el {{date}}",
|
||||
"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}}",
|
||||
"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}}",
|
||||
@@ -1744,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "Se han invitado {{userCount}} usuarios",
|
||||
"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",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}: No está autorizado para habilitar o deshabilitar este flujo de trabajo",
|
||||
"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.",
|
||||
"floating_pop_up_button": "Botón emergente flotante",
|
||||
@@ -1763,6 +1875,69 @@
|
||||
"connect_google_workspace": "Conectar Google Workspace",
|
||||
"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",
|
||||
"install_app_on": "Instalar aplicación en",
|
||||
"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",
|
||||
"yours": "Votre compte",
|
||||
"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.",
|
||||
"finish": "Terminer",
|
||||
"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",
|
||||
"meeting_ended": "Rendez-vous terminé",
|
||||
"form_submitted": "Formulaire envoyé",
|
||||
"booking_paid": "Réservation payée",
|
||||
"event_triggers": "Déclencheurs d'événement",
|
||||
"subscriber_url": "Lien de l'abonné",
|
||||
"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.",
|
||||
"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",
|
||||
"first_name": "Prénom",
|
||||
"last_name": "Nom",
|
||||
"first_last_name": "Prénom, Nom",
|
||||
"invite_as": "Inviter en tant que",
|
||||
"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",
|
||||
@@ -1939,6 +1945,7 @@
|
||||
"insights_team_filter": "Équipe : {{teamName}}",
|
||||
"insights_user_filter": "Utilisateur : {{userName}}",
|
||||
"insights_subtitle": "Visualisez les statistiques de réservation à travers vos événements",
|
||||
"location_options": "{{locationCount}} options de lieu",
|
||||
"custom_plan": "Plan personnalisé",
|
||||
"org_team_names_example": "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_4": "p. ex. Équipe d'ingénierie",
|
||||
"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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -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.",
|
||||
"organizer_timezone": "Fuso orario organizzatore",
|
||||
"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_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_two": "Collega il tuo account di calendario",
|
||||
"email_no_user_step_three": "Imposta la tua disponibilità",
|
||||
@@ -1669,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "Nessun flusso di lavoro",
|
||||
"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",
|
||||
"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.",
|
||||
@@ -1679,7 +1684,9 @@
|
||||
"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": "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_routing_form_on": "Crea modulo di instradamento su",
|
||||
"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.",
|
||||
"organizer_default_conferencing_app": "Applicazione predefinita dell'organizzatore",
|
||||
@@ -1700,6 +1707,7 @@
|
||||
"show_on_booking_page": "Mostra nella pagina di prenotazione",
|
||||
"get_started_zapier_templates": "Inizia con i modelli Zapier",
|
||||
"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",
|
||||
"a_routing_form": "Un modulo di instradamento",
|
||||
"form_description_placeholder": "Descrizione modulo",
|
||||
@@ -1731,6 +1739,7 @@
|
||||
"no_responses_yet": "Per ora non ci sono risposte",
|
||||
"no_routes_defined": "Nessun percorso definito",
|
||||
"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_description": "Seleziona una fascia oraria per prenotare l'evento.",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Rivedi tipo di evento",
|
||||
"looking_for_more_analytics": "Hai bisogno di più dati analitici?",
|
||||
@@ -1791,12 +1801,14 @@
|
||||
"least_booked_members": "Membri meno prenotati",
|
||||
"events_created": "Eventi creati",
|
||||
"events_completed": "Eventi completati",
|
||||
"events_cancelled": "Eventi cancellati",
|
||||
"events_rescheduled": "Eventi riprogrammati",
|
||||
"from_last_period": "dal periodo precedente",
|
||||
"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\".",
|
||||
"event_trends": "Tendenze eventi",
|
||||
"clear_filters": "Cancella filtri",
|
||||
"clear": "Cancella",
|
||||
"hold": "Preautorizzazione",
|
||||
"on_booking_option": "Raccogli pagamento alla prenotazione",
|
||||
"hold_option": "Addebita penale per mancata presentazione",
|
||||
@@ -1832,6 +1844,8 @@
|
||||
"one_day": "1 giorno",
|
||||
"seven_days": "7 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}}",
|
||||
"currency_string": "{{amount, currency}}",
|
||||
"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",
|
||||
"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",
|
||||
"install_app_on": "Installa l'app su",
|
||||
"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",
|
||||
"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)",
|
||||
"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_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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑"
|
||||
}
|
||||
|
||||
@@ -1880,5 +1880,64 @@
|
||||
"setup_organization": "Organization をセットアップ",
|
||||
"organization_banner_description": "チームがラウンドロビンスケジューリングや一括スケジューリングで、共有アプリ、ワークフロー、イベントの種類を作成できる環境を作成します。",
|
||||
"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": "↑↑↑↑↑↑↑↑↑↑↑↑↑ この上に新しい文字列を追加 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -13,11 +13,21 @@
|
||||
"reset_password_subject": "{{appName}}: Instructies voor het opnieuw instellen van uw wachtwoord",
|
||||
"verify_email_subject": "{{appName}}: Verifieer je account",
|
||||
"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_cancelled_subject": "Geannuleerd: {{title}} op {{date}}",
|
||||
"event_request_declined": "Uw gebeurtenisverzoek is geweigerd",
|
||||
"event_request_declined_recurring": "Uw verzoek voor een terugkerende gebeurtenis is geweigerd",
|
||||
"event_request_cancelled": "Uw geplande gebeurtenis is geannuleerd",
|
||||
"organizer": "Organisator",
|
||||
"need_to_reschedule_or_cancel": "Moet u verplaatsen of annuleren?",
|
||||
"no_options_available": "Geen opties beschikbaar",
|
||||
"cancellation_reason": "Reden voor annulering (optioneel)",
|
||||
"cancellation_reason_placeholder": "Waarom annuleert u?",
|
||||
"rejection_reason": "Reden voor weigering",
|
||||
@@ -77,7 +87,9 @@
|
||||
"your_meeting_has_been_booked": "Uw afspraak is geboekt",
|
||||
"event_type_has_been_rescheduled_on_time_date": "Uw {{title}} is verplaatst naar {{date}}.",
|
||||
"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_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}}",
|
||||
"requested_to_reschedule_subject_attendee": "Actie vereist voor verplaatsing: boek een nieuwe tijd voor {{eventType}} met {{name}}",
|
||||
"hi_user_name": "Hallo {{name}}",
|
||||
@@ -106,6 +118,7 @@
|
||||
"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.",
|
||||
"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_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.",
|
||||
@@ -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.",
|
||||
"upgrade_banner_action": "Hier upgraden",
|
||||
"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",
|
||||
"hey_there": "Hallo daar,",
|
||||
"forgot_your_password_calcom": "Wachtwoord vergeten? - {{appName}}",
|
||||
@@ -182,6 +197,7 @@
|
||||
"blog": "Blog",
|
||||
"blog_description": "Lees ons laatste nieuws en artikelen",
|
||||
"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",
|
||||
"popular_pages": "Populaire pagina's",
|
||||
"register_now": "Registreer nu",
|
||||
@@ -189,6 +205,7 @@
|
||||
"page_doesnt_exist": "Deze pagina bestaat niet.",
|
||||
"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.",
|
||||
"booker_event_not_found": "We kunnen de gebeurtenis die u probeert te boeken niet vinden.",
|
||||
"getting_started": "Aan de slag",
|
||||
"15min_meeting": "15 Minuten afspraak",
|
||||
"30min_meeting": "30 Minuten afspraak",
|
||||
@@ -224,11 +241,14 @@
|
||||
"done": "Voltooid",
|
||||
"all_done": "Helemaal klaar!",
|
||||
"all": "Alle apps",
|
||||
"yours": "Uw account",
|
||||
"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.",
|
||||
"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.",
|
||||
"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": "Beschikbaarheid bepalen",
|
||||
"continue_without_calendar": "Doorgaan zonder kalender",
|
||||
@@ -284,6 +304,18 @@
|
||||
"success": "Geslaagd",
|
||||
"failed": "Mislukt",
|
||||
"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.",
|
||||
"sunday_time_error": "Ongeldige tijd op zondag",
|
||||
"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",
|
||||
"back_to_bookings": "Terug naar afspraken",
|
||||
"free_to_pick_another_event_type": "U kunt op elk moment een andere afspraak maken.",
|
||||
"cancelled": "Geannuleerd",
|
||||
"cancellation_successful": "Annulering geslaagd",
|
||||
"really_cancel_booking": "Weet u zeker dat u deze afspraak wilt 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_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_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",
|
||||
"go_back_home": "Terug naar 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}}",
|
||||
"event_between_users": "{{eventName}} tussen {{host}} en {{attendeeName}}",
|
||||
"bookings": "Afspraken",
|
||||
"booking_not_found": "Boeking niet gevonden",
|
||||
"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.",
|
||||
"recurring_bookings": "Zodra iemand een terugkerende afspraak met u boekt, verschijnt die hier.",
|
||||
"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_tooltip": "Niet-bevestigde boekingen",
|
||||
"on": "aan",
|
||||
@@ -350,15 +391,19 @@
|
||||
"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": "Sta deelnemers toe om u te boeken via dynamische groepsboekingen",
|
||||
"dynamic_booking": "Dynamische groepslinks",
|
||||
"email": "E-mailadres",
|
||||
"email_placeholder": "jjansen@voorbeeld.nl",
|
||||
"full_name": "Volledige naam",
|
||||
"browse_api_documentation": "Bekijk onze API-documentatie",
|
||||
"leverage_our_api": "Gebruik onze API voor volledige controle en aanpasbaarheid.",
|
||||
"create_webhook": "Webhook maken",
|
||||
"booking_cancelled": "Boeking geannuleerd",
|
||||
"booking_rescheduled": "Afspraak verplaatst",
|
||||
"recording_ready": "Opnamedownloadlink gereed",
|
||||
"booking_created": "Boeking aangemaakt",
|
||||
"booking_rejected": "Boeking geweigerd",
|
||||
"booking_requested": "Boeking aangevraagd",
|
||||
"meeting_ended": "Vergadering beëindigd",
|
||||
"form_submitted": "Formulier verzonden",
|
||||
"event_triggers": "Webhook activaties",
|
||||
@@ -368,6 +413,8 @@
|
||||
"team_webhooks": "Teamwebhooks",
|
||||
"create_new_webhook_to_account": "Maak een nieuwe webhook aan voor uw account",
|
||||
"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",
|
||||
"loading": "Laden...",
|
||||
"deleting": "Verwijderen...",
|
||||
@@ -430,6 +477,7 @@
|
||||
"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",
|
||||
"incorrect_password": "Uw wachtwoord is incorrect.",
|
||||
"incorrect_email_password": "E-mailadres of wachtwoord is onjuist.",
|
||||
"use_setting": "Instelling gebruiken",
|
||||
"am_pm": "am/pm",
|
||||
"time_options": "Tijd, datum en tijdzone instellen",
|
||||
@@ -457,6 +505,7 @@
|
||||
"additional_guests": "Gasten toevoegen",
|
||||
"your_name": "Uw naam",
|
||||
"your_full_name": "Uw volledige naam",
|
||||
"no_name": "Geen naam",
|
||||
"email_address": "E-mail adres",
|
||||
"enter_valid_email": "Voer een geldig e-mailadres in",
|
||||
"location": "Locatie",
|
||||
@@ -500,10 +549,13 @@
|
||||
"your_team_updated_successfully": "Uw team is succesvol bijgewerkt.",
|
||||
"about": "Introductie",
|
||||
"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",
|
||||
"organization_members": "Organisatieleden",
|
||||
"member": "Lid",
|
||||
"number_member_one": "{{count}} lid",
|
||||
"number_member_other": "{{count}} leden",
|
||||
"number_selected": "{{count}} geselecteerd",
|
||||
"owner": "Eigenaar",
|
||||
"admin": "Beheerder",
|
||||
"administrator_user": "Beheerdersgebruiker",
|
||||
@@ -534,6 +586,8 @@
|
||||
"confirm_all": "Alles bevestigen",
|
||||
"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_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?",
|
||||
"confirm_disband_team": "Ja, ontbind team",
|
||||
"confirm_remove_member": "Ja, verwijder lid",
|
||||
@@ -608,6 +662,7 @@
|
||||
"event_type_updated_successfully": "Evenement is bijgewerkt",
|
||||
"event_type_deleted_successfully": "Evenement is verwijderd",
|
||||
"hours": "Uren",
|
||||
"people": "Mensen",
|
||||
"your_email": "Uw E-mailadres",
|
||||
"change_avatar": "Wijzig avatar",
|
||||
"language": "Taal",
|
||||
@@ -640,9 +695,11 @@
|
||||
"create_new_team": "Nieuw team aanmaken",
|
||||
"open_invitations": "Openstaande uitnodigingen",
|
||||
"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",
|
||||
"teams": "Teams",
|
||||
"team": "Team",
|
||||
"organization": "Organisatie",
|
||||
"team_billing": "Teamfacturatie",
|
||||
"team_billing_description": "Beheer de facturering voor uw team",
|
||||
"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_teams_meeting_url": "{{appName}} geeft een vergaderings-URL voor MS Teams. OPMERKING: MOET EEN WERK- OF SCHOOLACCOUNT HEBBEN",
|
||||
"require_payment": "Betaling vereisen",
|
||||
"you_need_to_add_a_name": "U moet een naam toevoegen",
|
||||
"commission_per_transaction": "commissie per transactie",
|
||||
"event_type_updated_successfully_description": "Uw evenement is met succes bijgewerkt.",
|
||||
"hide_event_type": "Verberg evenement",
|
||||
@@ -807,18 +865,25 @@
|
||||
"installed_apps": "Geinstalleerde apps",
|
||||
"free_to_use_apps": "Gratis",
|
||||
"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_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_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_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_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_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_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_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",
|
||||
"empty_installed_apps_headline": "Geen apps geïnstalleerd",
|
||||
"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",
|
||||
"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_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",
|
||||
"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.",
|
||||
@@ -913,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Deze API-sleutel intrekken",
|
||||
"revoke_api_key": "API-sleutel intrekken",
|
||||
"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?",
|
||||
"copy": "Kopiëren",
|
||||
"expire_date": "Verloopdatum",
|
||||
@@ -935,6 +1002,9 @@
|
||||
"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.",
|
||||
"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",
|
||||
"impersonate_user_tip": "Alle gebruik van deze functie wordt gecontroleerd.",
|
||||
"impersonating_user_warning": "Gebruikersnaam \"{{user}}\" wordt geïmiteerd.",
|
||||
@@ -1002,16 +1072,21 @@
|
||||
"event_location": "Locatie gebeurtenis",
|
||||
"reschedule_optional": "Reden voor verplaatsen (optioneel)",
|
||||
"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.",
|
||||
"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",
|
||||
"url_start_with_https": "URL moet beginnen met http:// of https://",
|
||||
"number_provided": "Telefoonnummer wordt verstrekt",
|
||||
"before_event_trigger": "voordat de gebeurtenis begint",
|
||||
"event_cancelled_trigger": "wanneer de gebeurtenis is geannuleerd",
|
||||
"new_event_trigger": "wanneer een nieuwe gebeurtenis is geboekt",
|
||||
"email_host_action": "e-mail naar organisator 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",
|
||||
"whatsapp_number_action": "WhatsApp-bericht naar een specifiek nummer versturen",
|
||||
"whatsapp_attendee_action": "WhatsApp-bericht naar deelnemer versturen",
|
||||
"workflows": "Werkstromen",
|
||||
"new_workflow_btn": "Nieuwe werkstroom",
|
||||
"add_new_workflow": "Een nieuwe werkstroom toevoegen",
|
||||
@@ -1075,6 +1150,8 @@
|
||||
"choose_template": "Kies een sjabloon",
|
||||
"custom": "Aangepast",
|
||||
"reminder": "Herinnering",
|
||||
"rescheduled": "Opnieuw gepland",
|
||||
"completed": "Voltooid",
|
||||
"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.",
|
||||
"minute_one": "{{count}} minuut",
|
||||
@@ -1172,6 +1249,7 @@
|
||||
"start_of_week": "Begin van de week",
|
||||
"recordings_title": "Opnames",
|
||||
"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.",
|
||||
"check_for_conflicts": "Controleer op conflicten",
|
||||
"view_recordings": "Opnames weergeven",
|
||||
@@ -1213,6 +1291,7 @@
|
||||
"conferencing_description": "Beheer uw favoriete apps voor videoconferenties voor uw vergaderingen",
|
||||
"add_conferencing_app": "Conferentieapp toevoegen",
|
||||
"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.",
|
||||
"skip": "Overslaan",
|
||||
"do_this_later": "Doe dit later",
|
||||
@@ -1226,6 +1305,8 @@
|
||||
"connect_analytics_apps": "Koppel analyse-apps",
|
||||
"connect_other_apps": "Andere 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}}",
|
||||
"add_variable": "Variabele toevoegen",
|
||||
"custom_phone_number": "Aangepast telefoonnummer",
|
||||
@@ -1238,12 +1319,14 @@
|
||||
"location_info": "De locatie van de gebeurtenis",
|
||||
"additional_notes_info": "De aanvullende opmerkingen bij de boeking",
|
||||
"attendee_name_info": "De naam van de persoon die boekt",
|
||||
"organizer_name_info": "Naam organisator",
|
||||
"to": "Aan",
|
||||
"workflow_turned_on_successfully": "De werkstroom {{workflowName}} is {{offOn}}",
|
||||
"download_responses": "Reacties downloaden",
|
||||
"download_responses_description": "Download alle reacties op uw formulier in CSV-indeling.",
|
||||
"download": "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_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",
|
||||
@@ -1252,7 +1335,9 @@
|
||||
"event_one": "gebeurtenis",
|
||||
"event_other": "gebeurtenissen",
|
||||
"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",
|
||||
"organization_description": "Beheer de beheerders en leden in uw organisatie",
|
||||
"team_url": "Team-URL",
|
||||
"team_members": "Teamleden",
|
||||
"more": "Meer",
|
||||
@@ -1293,6 +1378,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1378,6 +1464,7 @@
|
||||
"new_event_type_availability": "Beschikbaarheid {{eventTypeTitle}}",
|
||||
"error_editing_availability": "Fout bij het bewerken van de beschikbaarheid",
|
||||
"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_email_required": "Voer een e-mailadres in zodat we uw SAML-identiteitsprovider kunnen vinden",
|
||||
"saml_sp_title": "Serviceprovidergegevens",
|
||||
@@ -1396,15 +1483,19 @@
|
||||
"yearly": "Jaarlijks",
|
||||
"checkout": "Kassa",
|
||||
"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",
|
||||
"you": "U",
|
||||
"resend_email": "E-mail opnieuw versturen",
|
||||
"member_already_invited": "Lid is al uitgenodigd",
|
||||
"enter_email_or_username": "Voer een e-mailadres of gebruikersnaam in",
|
||||
"team_name_taken": "Deze naam is al in gebruik",
|
||||
"must_enter_team_name": "Moet een teamnaam invoeren",
|
||||
"team_url_required": "Moet een team-URL invoeren",
|
||||
"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",
|
||||
"number_text_notifications": "Telefoonnummer (berichtmeldingen)",
|
||||
"attendee_email_variable": "E-mailadres deelnemer",
|
||||
"attendee_email_info": "Het e-mailadres van de persoon die boekt",
|
||||
"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.",
|
||||
"fixed_round_robin": "Vaste round-robin",
|
||||
"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.",
|
||||
"booking_limit_reached": "Boekingslimiet 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",
|
||||
"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_description": "Schakel apps in die gebruikers kunnen integreren met {{appName}}",
|
||||
"purchase_license": "Koop een licentie",
|
||||
"already_have_key": "Ik heb al een code:",
|
||||
"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_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_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",
|
||||
"fill_this_field": "Vul dit veld in",
|
||||
"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.",
|
||||
"organizer_timezone": "Tijdzone organisator",
|
||||
"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_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_two": "Koppel uw agenda-account",
|
||||
"email_no_user_step_three": "Stel uw beschikbaarheid in",
|
||||
@@ -1572,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "Geen werkstromen",
|
||||
"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",
|
||||
"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.",
|
||||
@@ -1582,7 +1684,9 @@
|
||||
"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": "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_routing_form_on": "Maak routeringsformulier op",
|
||||
"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.",
|
||||
"organizer_default_conferencing_app": "Standaardapp organisator",
|
||||
@@ -1592,6 +1696,7 @@
|
||||
"booking_questions_title": "Boekingsvragen",
|
||||
"booking_questions_description": "Pas de gestelde vragen op de boekingspagina aan",
|
||||
"add_a_booking_question": "Vraag toevoegen",
|
||||
"identifier": "ID",
|
||||
"duplicate_email": "E-mailadres dubbel",
|
||||
"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.",
|
||||
@@ -1602,6 +1707,7 @@
|
||||
"show_on_booking_page": "Weergeven op boekingspagina",
|
||||
"get_started_zapier_templates": "Aan de slag met Zapier-sjablonen",
|
||||
"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",
|
||||
"a_routing_form": "Een routeringsformulier",
|
||||
"form_description_placeholder": "Formulierbeschrijving",
|
||||
@@ -1631,13 +1737,16 @@
|
||||
"spot_popular_event_types": "Spot populaire gebeurtenistypen",
|
||||
"spot_popular_event_types_description": "Bekijk welke van uw gebeurtenistypen de meeste kliks en boekingen ontvangen",
|
||||
"no_responses_yet": "Nog geen reacties",
|
||||
"no_routes_defined": "Geen routes bepaald",
|
||||
"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_description": "Selecteer een tijdslot om de gebeurtenis te boeken.",
|
||||
"timeslot_missing_cta": "Tijdslot selecteren",
|
||||
"switch_monthly": "Overschakelen naar maandelijkse weergave",
|
||||
"switch_weekly": "Overschakelen naar wekelijkse weergave",
|
||||
"switch_multiday": "Overschakelen naar dagelijkse weergave",
|
||||
"switch_columnview": "Overschakelen naar kolomweergave",
|
||||
"num_locations": "{{num}} locatieopties",
|
||||
"select_on_next_step": "Selecteer bij de volgende stap",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Gebeurtenistype bekijken",
|
||||
"looking_for_more_analytics": "Op zoek naar meer analyses?",
|
||||
@@ -1691,12 +1801,14 @@
|
||||
"least_booked_members": "Minst geboekte leden",
|
||||
"events_created": "Gemaakte gebeurtenissen",
|
||||
"events_completed": "Voltooide gebeurtenissen",
|
||||
"events_cancelled": "Geannuleerde gebeurtenissen",
|
||||
"events_rescheduled": "Verplaatste gebeurtenissen",
|
||||
"from_last_period": "van afgelopen periode",
|
||||
"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.",
|
||||
"event_trends": "Gebeurtenistrends",
|
||||
"clear_filters": "Filters wissen",
|
||||
"clear": "Wissen",
|
||||
"hold": "Vasthouden",
|
||||
"on_booking_option": "Betaling ontvangen bij boeken",
|
||||
"hold_option": "Afwezigheidsvergoeding in rekening brengen",
|
||||
@@ -1723,6 +1835,18 @@
|
||||
"complete_your_booking": "Voltooi uw boeking",
|
||||
"complete_your_booking_subject": "Voltooi uw boeking: {{title}} op {{date}}",
|
||||
"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}}",
|
||||
"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",
|
||||
@@ -1731,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "{{userCount}} gebruikers zijn uitgenodigd",
|
||||
"error_collecting_card": "Fout bij incasseren van kaart",
|
||||
"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",
|
||||
"load_inline_content": "Laadt uw gebeurtenistype rechtstreeks inline met uw andere websitecontent.",
|
||||
"floating_pop_up_button": "Zwevende pop-upknop",
|
||||
@@ -1750,6 +1875,69 @@
|
||||
"connect_google_workspace": "Google Workspace koppelen",
|
||||
"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",
|
||||
"install_app_on": "Installeer app op",
|
||||
"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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -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.",
|
||||
"have_any_questions": "Masz pytania? Jesteśmy tutaj, aby pomóc.",
|
||||
"reset_password_subject": "{{appName}}: Instrukcje resetowania hasła",
|
||||
"verify_email_subject": "{{appName}}: Zweryfikuj swoje konto",
|
||||
"check_your_email": "Sprawdź swój e-mail",
|
||||
"verify_email_subject": "{{appName}}: zweryfikuj swoje konto",
|
||||
"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_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_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_cancelled_subject": "Anulowano: {{title}}, {{date}}",
|
||||
"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_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_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.",
|
||||
"sunday_time_error": "Nieprawidłowy czas na niedzielę",
|
||||
"monday_time_error": "Nieprawidłowy czas na poniedziałek",
|
||||
@@ -348,7 +352,7 @@
|
||||
"no_status_bookings_yet_description": "Nie masz {{status}} rezerwacji. {{description}}",
|
||||
"event_between_users": "{{eventName}} między {{host}} a {{attendeeName}}",
|
||||
"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.",
|
||||
"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.",
|
||||
@@ -1075,7 +1079,7 @@
|
||||
"url_start_with_https": "Adres URL musi zaczynać się od http:// lub https://",
|
||||
"number_provided": "Numer telefonu zostanie podany.",
|
||||
"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",
|
||||
"email_host_action": "wyślij wiadomość e-mail do hosta",
|
||||
"email_attendee_action": "wyślij wiadomość e-mail do uczestników",
|
||||
@@ -1479,7 +1483,7 @@
|
||||
"yearly": "Co rok",
|
||||
"checkout": "Do kasy",
|
||||
"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",
|
||||
"you": "Ty",
|
||||
"resend_email": "Wyślij wiadomość e-mail ponownie",
|
||||
@@ -1703,6 +1707,7 @@
|
||||
"show_on_booking_page": "Pokaż na stronie rezerwacji",
|
||||
"get_started_zapier_templates": "Zacznij korzystać z szablonów Zapier",
|
||||
"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",
|
||||
"a_routing_form": "Formularz przekierowania",
|
||||
"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_description": "Zobacz, które typy wydarzeń są najczęściej klikane i rezerwowane",
|
||||
"no_responses_yet": "Nie ma jeszcze odpowiedzi",
|
||||
"no_routes_defined": "Brak zdefiniowanych przekierowań",
|
||||
"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_description": "Wybierz przedział czasowy, aby zarezerwować wydarzenie.",
|
||||
"timeslot_missing_cta": "Wybierz przedział czasowy",
|
||||
"switch_monthly": "Przełącz na widok miesiąca",
|
||||
"switch_weekly": "Przełącz na widok tygodnia",
|
||||
"switch_multiday": "Przełącz na widok dnia",
|
||||
"switch_columnview": "Przełącz na widok kolumny",
|
||||
"num_locations": "Lokalizacje do wyboru: {{num}}",
|
||||
"select_on_next_step": "Wybierz następny krok",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Sprawdź typ wydarzenia",
|
||||
"looking_for_more_analytics": "Szukasz dokładniejszych danych analitycznych?",
|
||||
@@ -1792,12 +1801,14 @@
|
||||
"least_booked_members": "Najrzadziej rezerwowani członkowie",
|
||||
"events_created": "Utworzone wydarzenia",
|
||||
"events_completed": "Ukończone wydarzenia",
|
||||
"events_cancelled": "Anulowane wydarzenia",
|
||||
"events_rescheduled": "Przełożone wydarzenia",
|
||||
"from_last_period": "od ostatniego okresu",
|
||||
"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.",
|
||||
"event_trends": "Trendy wydarzeń",
|
||||
"clear_filters": "Wyczyść filtry",
|
||||
"clear": "Wyczyść",
|
||||
"hold": "Zablokowano",
|
||||
"on_booking_option": "Pobierz płatność przy rezerwacji",
|
||||
"hold_option": "Pobierz opłatę za niestawienie się",
|
||||
@@ -1824,6 +1835,18 @@
|
||||
"complete_your_booking": "Ukończ rezerwację",
|
||||
"complete_your_booking_subject": "Ukończ rezerwację: {{title}} dnia {{date}}",
|
||||
"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}}",
|
||||
"charge_card_dialog_body": "Zamierzasz obciążyć uczestnika kwotą {{amount, currency}}. Czy na pewno chcesz kontynuować?",
|
||||
"charge_attendee": "Obciąż uczestnika kwotą {{amount, currency}}",
|
||||
@@ -1832,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "Zaproszono {{userCount}} użytkowników",
|
||||
"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",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}: nie masz uprawnień do włączenia lub wyłączenia tego przepływu pracy.",
|
||||
"inline_embed": "Osadź w stronie",
|
||||
"load_inline_content": "Wczytuje typ wydarzenia bezpośrednio w treści Twojej strony internetowej.",
|
||||
"floating_pop_up_button": "Pływający przycisk wyskakujący",
|
||||
@@ -1851,6 +1875,69 @@
|
||||
"connect_google_workspace": "Podłącz usługę Google 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",
|
||||
"install_app_on": "Zainstaluj aplikację na:",
|
||||
"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_web3_apps": "Conecte aplicativos web3",
|
||||
"connect_messaging_apps": "Conectar com aplicativos de mensagem",
|
||||
"connect_crm_apps": "Conecte aplicativos CRM",
|
||||
"current_step_of_total": "Passo {{currentStep}} de {{maxSteps}}",
|
||||
"add_variable": "Adicionar variável",
|
||||
"custom_phone_number": "Número de telefone personalizado",
|
||||
@@ -1318,12 +1319,14 @@
|
||||
"location_info": "O local do evento",
|
||||
"additional_notes_info": "Notas adicionais da reserva",
|
||||
"attendee_name_info": "O nome da pessoa que fez a reserva",
|
||||
"organizer_name_info": "Nome do organizador",
|
||||
"to": "Para",
|
||||
"workflow_turned_on_successfully": "Fluxo de trabalho {{workflowName}} atualizado para {{offOn}} com sucesso",
|
||||
"download_responses": "Baixar respostas",
|
||||
"download_responses_description": "Baixe todas as respostas para seu formulário em formato CSV.",
|
||||
"download": "Baixar",
|
||||
"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_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",
|
||||
@@ -1332,7 +1335,9 @@
|
||||
"event_one": "evento",
|
||||
"event_other": "eventos",
|
||||
"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",
|
||||
"organization_description": "Gerencie os administradores e membros da sua organização",
|
||||
"team_url": "URL da equipe",
|
||||
"team_members": "Membros da equipe",
|
||||
"more": "Mais",
|
||||
@@ -1373,6 +1378,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1458,6 +1464,7 @@
|
||||
"new_event_type_availability": "Disponibilidade de {{eventTypeTitle}}",
|
||||
"error_editing_availability": "Erro ao editar disponibilidade",
|
||||
"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_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",
|
||||
@@ -1476,15 +1483,19 @@
|
||||
"yearly": "Anual",
|
||||
"checkout": "Finalizar compra",
|
||||
"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",
|
||||
"you": "Você",
|
||||
"resend_email": "Reenviar e-mail",
|
||||
"member_already_invited": "O membro já foi convidado",
|
||||
"enter_email_or_username": "Insira um e-mail ou nome de usuário",
|
||||
"team_name_taken": "Este nome já está em uso",
|
||||
"must_enter_team_name": "É preciso inserir um nome de equipe",
|
||||
"team_url_required": "É preciso inserir uma URL de equipe",
|
||||
"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",
|
||||
"number_text_notifications": "Número de telefone (notificações via texto)",
|
||||
"attendee_email_variable": "E-mail do participante",
|
||||
"attendee_email_info": "O e-mail da pessoa que fez a reserva",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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",
|
||||
@@ -1525,6 +1538,7 @@
|
||||
"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.",
|
||||
"enable_apps": "Ativar aplicativos",
|
||||
"enable_apps_description": "Ative aplicativos que os usuários podem integrar com o {{appName}}",
|
||||
"purchase_license": "Comprar uma licença",
|
||||
"already_have_key": "Já tenho uma chave:",
|
||||
"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_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_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",
|
||||
"fill_this_field": "Preencha este campo",
|
||||
"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.",
|
||||
"organizer_timezone": "Fuso horário do organizador",
|
||||
"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_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_two": "Conecte com sua conta de calendário",
|
||||
"email_no_user_step_three": "Defina sua disponibilidade",
|
||||
@@ -1652,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "Sem fluxos de trabalho",
|
||||
"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",
|
||||
"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.",
|
||||
@@ -1662,7 +1684,9 @@
|
||||
"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": "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_routing_form_on": "Criar formulário de roteamento em",
|
||||
"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.",
|
||||
"organizer_default_conferencing_app": "Aplicativo padrão do organizador",
|
||||
@@ -1672,6 +1696,7 @@
|
||||
"booking_questions_title": "Perguntas sobre reserva",
|
||||
"booking_questions_description": "Personalize as perguntas feitas na página de reservas",
|
||||
"add_a_booking_question": "Adicione uma pergunta",
|
||||
"identifier": "Identificador",
|
||||
"duplicate_email": "Este e-mail já existe",
|
||||
"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.",
|
||||
@@ -1682,6 +1707,7 @@
|
||||
"show_on_booking_page": "Mostrar na página de reservas",
|
||||
"get_started_zapier_templates": "Comece agora com modelos do Zapier",
|
||||
"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",
|
||||
"a_routing_form": "Formulário de roteamento",
|
||||
"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_description": "Veja quais tipos de eventos estão recebendo a maioria dos cliques e reservas",
|
||||
"no_responses_yet": "Sem respostas por enquanto",
|
||||
"no_routes_defined": "Nenhuma rota definida",
|
||||
"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_description": "Selecione uma alocação de tempo para reservar o evento.",
|
||||
"timeslot_missing_cta": "Selecione a alocação de tempo",
|
||||
"switch_monthly": "Trocar para visualização mensal",
|
||||
"switch_weekly": "Trocar para visualização semanal",
|
||||
"switch_multiday": "Trocar para visualização diária",
|
||||
"switch_columnview": "Trocar para visualização de coluna",
|
||||
"num_locations": "{{num}} opções de local",
|
||||
"select_on_next_step": "Selecione na próxima etapa",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Revisar tipo de evento",
|
||||
"looking_for_more_analytics": "Procurando mais análises?",
|
||||
@@ -1771,12 +1801,14 @@
|
||||
"least_booked_members": "Membros com menos reservas",
|
||||
"events_created": "Eventos criados",
|
||||
"events_completed": "Eventos concluídos",
|
||||
"events_cancelled": "Eventos cancelados",
|
||||
"events_rescheduled": "Eventos reagendados",
|
||||
"from_last_period": "do último período",
|
||||
"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.",
|
||||
"event_trends": "Tendências de evento",
|
||||
"clear_filters": "Limpar filtros",
|
||||
"clear": "Limpar",
|
||||
"hold": "Segurar",
|
||||
"on_booking_option": "Coletar pagamento na reserva",
|
||||
"hold_option": "Carregar taxa de não comparecimento",
|
||||
@@ -1803,6 +1835,18 @@
|
||||
"complete_your_booking": "Conclua sua reserva",
|
||||
"complete_your_booking_subject": "Conclua sua reserva: {{title}} à(s) {{date}}",
|
||||
"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}}",
|
||||
"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",
|
||||
@@ -1811,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "{{userCount}} usuários foram convidados",
|
||||
"error_collecting_card": "Erro ao coletar cartão",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1830,6 +1875,69 @@
|
||||
"connect_google_workspace": "Conectar com o Google Workspace",
|
||||
"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",
|
||||
"install_app_on": "Instalar aplicativo em",
|
||||
"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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -14,12 +14,20 @@
|
||||
"verify_email_subject": "{{appName}}: Подтвердите учетную запись",
|
||||
"check_your_email": "Проверьте почту",
|
||||
"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_cancelled_subject": "Отмена: {{title}} {{date}}",
|
||||
"event_request_declined": "Ваш запрос на встречу отклонен",
|
||||
"event_request_declined_recurring": "Ваш запрос на повторяющееся событие отклонен",
|
||||
"event_request_cancelled": "Ваша запланированная встреча была отменена",
|
||||
"organizer": "Организатор",
|
||||
"need_to_reschedule_or_cancel": "Хотите перенести или отменить?",
|
||||
"no_options_available": "Нет доступных вариантов",
|
||||
"cancellation_reason": "Причина отмены (необязательно)",
|
||||
"cancellation_reason_placeholder": "Укажите причину отмены подписки",
|
||||
"rejection_reason": "Причина отказа",
|
||||
@@ -79,7 +87,9 @@
|
||||
"your_meeting_has_been_booked": "Ваша встреча была забронирована",
|
||||
"event_type_has_been_rescheduled_on_time_date": "Ваше {{title}} было перенесено на {{date}}.",
|
||||
"event_has_been_rescheduled": "Ваше событие было перенесено.",
|
||||
"request_reschedule_subtitle": "{{organizer}} отменил(-а) бронирование и попросил(-а) вас выбрать другое время.",
|
||||
"request_reschedule_title_organizer": "Вы запросили у {{attendee}} изменение расписания",
|
||||
"request_reschedule_subtitle_organizer": "Вы отменили бронирование; теперь {{attendee}} и вам нужно выбрать новое время.",
|
||||
"rescheduled_event_type_subject": "Запрос на перенос отправлен: {{eventType}} с {{name}}, {{date}}",
|
||||
"requested_to_reschedule_subject_attendee": "Требуется перенести бронирование: забронируйте новое время для {{eventType}} с {{name}}",
|
||||
"hi_user_name": "Привет {{name}}",
|
||||
@@ -120,6 +130,7 @@
|
||||
"upgrade_banner_action": "Изменить",
|
||||
"team_upgraded_successfully": "Вы успешно перешли на новый тариф для своей команды!",
|
||||
"org_upgrade_banner_description": "Спасибо, что попробовали наш новый тариф Organization. Для работы с «{{teamName}}» нужно перейти на тариф Organization.",
|
||||
"org_upgraded_successfully": "Вы успешно перешли на тариф Organization!",
|
||||
"use_link_to_reset_password": "Используйте ссылку ниже, чтобы сбросить пароль",
|
||||
"hey_there": "Привет,",
|
||||
"forgot_your_password_calcom": "Забыли пароль? - {{appName}}",
|
||||
@@ -186,6 +197,7 @@
|
||||
"blog": "Блог",
|
||||
"blog_description": "Прочитайте наши последние новости и статьи",
|
||||
"join_our_community": "Присоединяйтесь к нашему сообществу",
|
||||
"join_our_discord": "Присоединяйтесь к нам в Discord",
|
||||
"404_claim_entity_user": "Забронируйте своё имя пользователя и начните планировать встречи",
|
||||
"popular_pages": "Популярные страницы",
|
||||
"register_now": "Зарегистрироваться",
|
||||
@@ -193,6 +205,7 @@
|
||||
"page_doesnt_exist": "Эта страница не существует.",
|
||||
"check_spelling_mistakes_or_go_back": "Проверьте наличие ошибок, или вернитесь на предыдущую страницу.",
|
||||
"404_page_not_found": "404: Страница не найдена.",
|
||||
"booker_event_not_found": "Нам не удалось найти событие, которое вы пытаетесь забронировать.",
|
||||
"getting_started": "Начало работы",
|
||||
"15min_meeting": "Встреча на 15 минут",
|
||||
"30min_meeting": "Встреча на 30 минут",
|
||||
@@ -228,11 +241,14 @@
|
||||
"done": "Готово",
|
||||
"all_done": "Готово!",
|
||||
"all": "Все приложения",
|
||||
"yours": "Ваш аккаунт",
|
||||
"available_apps": "Доступные приложения",
|
||||
"check_email_reset_password": "Проверьте вашу электронную почту, мы отправили вам ссылку для сброса пароля.",
|
||||
"finish": "Завершить",
|
||||
"organization_general_description": "Настройте язык и часовой пояс для своей команды",
|
||||
"few_sentences_about_yourself": "Напишите несколько предложений о себе. Они будут отображаться на вашей публичной странице.",
|
||||
"nearly_there": "Почти готово!",
|
||||
"nearly_there_instructions": "И последнее: добавьте краткую информацию о себе и свою фотографию; так людям будет проще понять, с кем они бронируют встречу.",
|
||||
"set_availability_instructions": "Определите диапазон времени, в который вы обычно доступны. В дальнейшем можно будет добавить ещё диапазоны и назначить их разным календарям.",
|
||||
"set_availability": "Задайте время в которое вы доступны",
|
||||
"continue_without_calendar": "Продолжить без подключения календаря",
|
||||
@@ -288,7 +304,18 @@
|
||||
"success": "Успешно",
|
||||
"failed": "Ошибка",
|
||||
"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_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": "Произошла непредвиденная ошибка. Попробуйте еще раз.",
|
||||
"sunday_time_error": "Недопустимое время в воскресенье",
|
||||
"monday_time_error": "Недопустимое время в понедельник",
|
||||
@@ -301,6 +328,7 @@
|
||||
"error_end_time_next_day": "Время окончания не может позже 24 часов",
|
||||
"back_to_bookings": "Вернуться к списку бронирований",
|
||||
"free_to_pick_another_event_type": "Вы можете выбрать любое другое событие.",
|
||||
"cancelled": "Отменено",
|
||||
"cancellation_successful": "Отмена прошла успешно",
|
||||
"really_cancel_booking": "Вы действительно хотите отменить бронирование?",
|
||||
"cannot_cancel_booking": "Вы не можете отменить это бронирование",
|
||||
@@ -309,6 +337,12 @@
|
||||
"cancelling_event_recurring": "Данное событие — один из экземпляров повторяющегося события.",
|
||||
"cancelling_all_recurring": "Это все оставшиеся экземпляры повторяющегося события.",
|
||||
"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": "Это бронирование уже принято или отклонено",
|
||||
"go_back_home": "Вернуться домой",
|
||||
"or_go_back_home": "Или вернитесь домой",
|
||||
@@ -318,10 +352,12 @@
|
||||
"no_status_bookings_yet_description": "У вас нет {{status}} бронирований. {{description}}",
|
||||
"event_between_users": "{{eventName}} между {{host}} и {{attendeeName}}",
|
||||
"bookings": "Бронирования",
|
||||
"booking_not_found": "Бронирование не найдено",
|
||||
"bookings_description": "Просматривайте предстоящие и прошедшие события, забронированные по ссылкам событий.",
|
||||
"upcoming_bookings": "Как только кто-то забронирует встречу с вами она будет отображена здесь.",
|
||||
"recurring_bookings": "Как только кто-то забронирует повторяющуюся встречу с вами, она будет отображена здесь.",
|
||||
"past_bookings": "Здесь появятся ваши прошлые бронирования.",
|
||||
"cancelled_bookings": "Здесь появятся ваши отменённые бронирования.",
|
||||
"unconfirmed_bookings": "Здесь можно увидеть бронирования, которые вы еще не подтвердили.",
|
||||
"unconfirmed_bookings_tooltip": "Неподтвержденные бронирования",
|
||||
"on": "на",
|
||||
@@ -355,15 +391,19 @@
|
||||
"user_dynamic_booking_disabled": "Некоторые участники группы отключили функцию динамического группового бронирования",
|
||||
"allow_dynamic_booking_tooltip": "Ссылки для группового бронирования, которые можно создавать динамически, указывая несколько имен пользователей при помощи знака «+». Пример: «{{appName}}/bailey+peer»",
|
||||
"allow_dynamic_booking": "Разрешить участникам бронировать встречи с вами при помощи динамического группового бронирования",
|
||||
"dynamic_booking": "Динамические ссылки группы",
|
||||
"email": "Адрес электронной почты",
|
||||
"email_placeholder": "jdoe@example.com",
|
||||
"full_name": "Имя",
|
||||
"browse_api_documentation": "Посмотрите нашу документацию API",
|
||||
"leverage_our_api": "Используйте наш API для возможности полного управления и настройки.",
|
||||
"create_webhook": "Создать веб-хук",
|
||||
"booking_cancelled": "Бронирование отменено",
|
||||
"booking_rescheduled": "Бронирование изменено",
|
||||
"recording_ready": "Ссылка для скачивания записи готова",
|
||||
"booking_created": "Бронирование создано",
|
||||
"booking_rejected": "Бронирование отклонено",
|
||||
"booking_requested": "Поступил запрос на бронирование",
|
||||
"meeting_ended": "Встреча завершилась",
|
||||
"form_submitted": "Форма отправлена",
|
||||
"event_triggers": "Триггеры событий",
|
||||
@@ -373,6 +413,8 @@
|
||||
"team_webhooks": "Командные вебхуки",
|
||||
"create_new_webhook_to_account": "Создайте новый вебхук для вашей учетной записи",
|
||||
"new_webhook": "Новый веб-хук",
|
||||
"receive_cal_meeting_data": "Получайте данные о создании или отмене встреч в {{appName}} по указанному URL-адресу в реальном времени.",
|
||||
"receive_cal_event_meeting_data": "Получайте данные о планировании или отмене этого события в {{appName}} по указанному URL-адресу в реальном времени.",
|
||||
"responsive_fullscreen_iframe": "Адаптивный полноэкранный iframe",
|
||||
"loading": "Загрузка...",
|
||||
"deleting": "Выполняется удаление...",
|
||||
@@ -435,6 +477,7 @@
|
||||
"max_limit_allowed_hint": "Не более {{limit}} символов",
|
||||
"invalid_password_hint": "Пароль должен быть не короче {{passwordLength}} символов и содержать заглавные и строчные буквы, а также не менее одной цифры",
|
||||
"incorrect_password": "Неверный пароль",
|
||||
"incorrect_email_password": "Неверный адрес электронной почты или пароль.",
|
||||
"use_setting": "Использовать настройки",
|
||||
"am_pm": "am/pm",
|
||||
"time_options": "Настройки времени",
|
||||
@@ -462,6 +505,7 @@
|
||||
"additional_guests": "Добавить гостей",
|
||||
"your_name": "Ваше имя",
|
||||
"your_full_name": "ФИО",
|
||||
"no_name": "Нет имени",
|
||||
"email_address": "Адрес электронной почты",
|
||||
"enter_valid_email": "Укажите допустимый адрес электронной почты",
|
||||
"location": "Местоположение",
|
||||
@@ -505,7 +549,9 @@
|
||||
"your_team_updated_successfully": "Ваша команда успешно обновлена.",
|
||||
"about": "О нас",
|
||||
"team_description": "Краткое описание вашей команды. Этот текст будет показываться на странице вашей команды.",
|
||||
"org_description": "Краткое описание вашей организации. Этот текст будет виден на странице вашей организации.",
|
||||
"members": "Участники",
|
||||
"organization_members": "Сотрудники организации",
|
||||
"member": "Участник",
|
||||
"number_member_one": "Участники: {{count}}",
|
||||
"number_member_other": "Участники: {{count}}",
|
||||
@@ -540,6 +586,8 @@
|
||||
"confirm_all": "Подтвердить все",
|
||||
"disband_team": "Распустить команду",
|
||||
"disband_team_confirmation_message": "Вы уверены, что хотите распустить эту команду? Любой, с кем вы поделились ссылкой на эту команду, больше не сможет забронировать её.",
|
||||
"disband_org": "Распустить организацию",
|
||||
"disband_org_confirmation_message": "Распустить эту организацию? Все команды и сотрудники будут удалены.",
|
||||
"remove_member_confirmation_message": "Вы уверены, что хотите удалить этого участника из команды?",
|
||||
"confirm_disband_team": "Да, распустить команду",
|
||||
"confirm_remove_member": "Да, удалить участника",
|
||||
@@ -614,6 +662,7 @@
|
||||
"event_type_updated_successfully": "Тип события {{eventTypeTitle}} успешно обновлен",
|
||||
"event_type_deleted_successfully": "Тип события успешно удален",
|
||||
"hours": "Часы",
|
||||
"people": "Люди",
|
||||
"your_email": "Ваш адрес электронной почты",
|
||||
"change_avatar": "Изменить аватар",
|
||||
"language": "Язык",
|
||||
@@ -646,9 +695,11 @@
|
||||
"create_new_team": "Создание новой команды",
|
||||
"open_invitations": "Открыть список приглашений",
|
||||
"new_team": "Новая команда",
|
||||
"create_first_team_and_invite_others": "Создайте свою первую команду и пригласите других пользователей работать вместе с вами.",
|
||||
"create_team_to_get_started": "Создайте команду, чтобы начать работу",
|
||||
"teams": "Команды",
|
||||
"team": "Команда",
|
||||
"organization": "Организация",
|
||||
"team_billing": "Условия расчета для команд",
|
||||
"team_billing_description": "Управление биллингом вашей команды",
|
||||
"upgrade_to_flexible_pro_title": "Мы изменили условия расчета для команд",
|
||||
@@ -723,6 +774,7 @@
|
||||
"cal_provide_huddle01_meeting_url": "{{appName}} создаст ссылку на встречу в Huddle01 Web3.",
|
||||
"cal_provide_teams_meeting_url": "{{appName}} предоставит URL-адрес встречи в MS Teams. ПРИМЕЧАНИЕ: У ВАС ДОЛЖЕН БЫТЬ КОРПОРАТИВНЫЙ ИЛИ СТУДЕНЧЕСКИЙ АККАУНТ",
|
||||
"require_payment": "Требуется оплата",
|
||||
"you_need_to_add_a_name": "Нужно добавить имя",
|
||||
"commission_per_transaction": "комиссия за сделку",
|
||||
"event_type_updated_successfully_description": "Ваш шаблон события успешно обновлён.",
|
||||
"hide_event_type": "Скрыть шаблон события",
|
||||
@@ -813,18 +865,25 @@
|
||||
"installed_apps": "Установленные приложения",
|
||||
"free_to_use_apps": "Бесплатные",
|
||||
"no_category_apps": "Нет приложений в категории «{{category}}»",
|
||||
"all_apps": "Все приложения",
|
||||
"no_category_apps_description_calendar": "Добавьте приложение календаря, чтобы проверять наличие конфликтов для избежания двойного бронирования",
|
||||
"no_category_apps_description_conferencing": "Попробуйте добавить приложение конференц-связи для интеграции видеозвонков с клиентами",
|
||||
"no_category_apps_description_payment": "Добавьте платежное приложение, чтобы упростить транзакции с клиентами",
|
||||
"no_category_apps_description_analytics": "Добавьте приложение аналитики для использования на страницах бронирования",
|
||||
"no_category_apps_description_automation": "Добавьте приложение для автоматизации",
|
||||
"no_category_apps_description_other": "Добавляйте всевозможные приложения для решения своих задач",
|
||||
"no_category_apps_description_web3": "Добавьте приложение web3 для использования на страницах бронирования",
|
||||
"no_category_apps_description_messaging": "Добавьте мессенджер, чтобы настроить пользовательские уведомления и напоминания",
|
||||
"no_category_apps_description_crm": "Добавьте CRM, чтобы отслеживать, с кем у вас были встречи",
|
||||
"installed_app_calendar_description": "Настройте проверку календарей на предмет конфликтов для избежания двойного бронирования.",
|
||||
"installed_app_payment_description": "Выберите службы обработки платежей для получения оплаты от клиентов.",
|
||||
"installed_app_analytics_description": "Выберите приложения аналитики для страниц бронирования",
|
||||
"installed_app_other_description": "Все установленные приложения из других категорий.",
|
||||
"installed_app_conferencing_description": "Выберите приложения для видеоконференций",
|
||||
"installed_app_automation_description": "Выберите приложения для автоматизации",
|
||||
"installed_app_web3_description": "Выберите приложения web3 для страниц бронирования",
|
||||
"installed_app_messaging_description": "Выберите мессенджеры, в которых вы хотите настроить пользовательские уведомления и напоминания",
|
||||
"installed_app_crm_description": "Выберите CRM-приложения, в которых вы хотите отслеживать, с кем у вас были встречи",
|
||||
"analytics": "Аналитика",
|
||||
"empty_installed_apps_headline": "Нет установленных приложений",
|
||||
"empty_installed_apps_description": "Приложения позволяют значительно улучшить рабочий процесс и жить по расписанию.",
|
||||
@@ -850,6 +909,7 @@
|
||||
"create_events_on": "Создавать события в календаре:",
|
||||
"enterprise_license": "Это функция корпоративного тарифного плана",
|
||||
"enterprise_license_description": "Чтобы включить эту функцию, получите ключ развертывания на консоли {{consoleUrl}} и добавьте его в .env как CALCOM_LICENSE_KEY. Если у вашей команды уже есть лицензия, пожалуйста, обратитесь за помощью в {{supportMail}}.",
|
||||
"enterprise_license_development": "Протестируйте эту функцию в режиме разработки. Для использования в рабочем режиме администратор должен перейти по ссылке <2>/auth/setup</2> и ввести лицензионный ключ.",
|
||||
"missing_license": "Отсутствует лицензия",
|
||||
"signup_requires": "Требуется коммерческая лицензия",
|
||||
"signup_requires_description": "В настоящее время компания {{companyName}} не предлагает бесплатную версию страницы регистрации с открытым исходным кодом. Чтобы получить полный доступ к компонентам входа в систему, необходимо приобрести коммерческую лицензию. Для личного пользования мы рекомендуем Prisma Data Platform или любой другой интерфейс Postgres для создания учетных записей.",
|
||||
@@ -919,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Отозвать ключ API",
|
||||
"revoke_api_key": "Отозвать ключ API",
|
||||
"api_key_copied": "Ключ API скопирован.",
|
||||
"api_key_expires_on": "Срок действия ключа API истекает",
|
||||
"delete_api_key_confirm_title": "Удалить этот ключ API из вашего аккаунта навсегда?",
|
||||
"copy": "Копировать",
|
||||
"expire_date": "Срок действия",
|
||||
@@ -941,6 +1002,9 @@
|
||||
"user_impersonation_heading": "Вход от имени пользователя",
|
||||
"user_impersonation_description": "Позволяет нашей службе поддержки временно входить в систему от вашего имени, чтобы быстро решать любые проблемы, о которых вы нам сообщаете.",
|
||||
"team_impersonation_description": "Позволяет участникам и администраторам вашей команды временно входить в систему под вашим именем.",
|
||||
"make_team_private": "Сделать команду защищенной",
|
||||
"make_team_private_description": "Если эта опция включена, участники вашей команды не смогут видеть других участников команды.",
|
||||
"you_cannot_see_team_members": "Вы не можете видеть всех участников защищенной команды.",
|
||||
"allow_booker_to_select_duration": "Разрешить пользователю, оформляющему бронирование, выбирать длительность",
|
||||
"impersonate_user_tip": "Все варианты использования этой функции проверяются.",
|
||||
"impersonating_user_warning": "Олицетворение пользователя \"{{user}}\".",
|
||||
@@ -1008,17 +1072,21 @@
|
||||
"event_location": "Местоположение события",
|
||||
"reschedule_optional": "Причина переноса (дополнительно)",
|
||||
"reschedule_placeholder": "Расскажите другим, почему вам нужно изменить расписание",
|
||||
"event_cancelled": "Это событие отменено",
|
||||
"emailed_information_about_cancelled_event": "Мы сообщили об этом вам и другим участникам по электронной почте.",
|
||||
"this_input_will_shown_booking_this_event": "Этот вопрос будет показан при бронировании события по этому шаблону",
|
||||
"meeting_url_in_conformation_email": "Ссылка на встречу находится в письме с подтверждением",
|
||||
"url_start_with_https": "URL-адрес должен начинаться с http:// или https://",
|
||||
"number_provided": "Будет указан номер телефона",
|
||||
"before_event_trigger": "до начала события",
|
||||
"event_cancelled_trigger": "когда событие отменено",
|
||||
"new_event_trigger": "когда будет забронировано новое событие",
|
||||
"email_host_action": "отправить письмо организатору",
|
||||
"email_attendee_action": "отправить письмо участникам",
|
||||
"sms_attendee_action": "Отправить SMS-сообщение участнику",
|
||||
"sms_number_action": "отправка SMS-сообщение на указанный номер",
|
||||
"whatsapp_number_action": "отправка сообщение в Whatsapp на указанный номер",
|
||||
"whatsapp_attendee_action": "отправить участнику сообщение в Whatsapp",
|
||||
"workflows": "Рабочие процессы",
|
||||
"new_workflow_btn": "Новый рабочий процесс",
|
||||
"add_new_workflow": "Добавить новый рабочий процесс",
|
||||
@@ -1181,6 +1249,7 @@
|
||||
"start_of_week": "Начало недели",
|
||||
"recordings_title": "Записи",
|
||||
"recording": "Запись",
|
||||
"happy_scheduling": "Счастливого планирования",
|
||||
"select_calendars": "Выберите, в каких календарях нужно проверить наличие конфликтов и дублированного бронирования.",
|
||||
"check_for_conflicts": "Проверить наличие конфликтов",
|
||||
"view_recordings": "Просмотреть записи",
|
||||
@@ -1222,6 +1291,7 @@
|
||||
"conferencing_description": "Настройка приложений для видеоконференций, используемых для проведения онлайн-встреч",
|
||||
"add_conferencing_app": "Добавить приложение для видеоконференций",
|
||||
"password_description": "Настройка паролей для аккаунта",
|
||||
"set_up_two_factor_authentication": "Настроить двухфакторную аутентификацию",
|
||||
"we_just_need_basic_info": "Для настройки вашего профиля необходимо указать основную информацию.",
|
||||
"skip": "Пропустить",
|
||||
"do_this_later": "Настроить позже",
|
||||
@@ -1235,6 +1305,8 @@
|
||||
"connect_analytics_apps": "Подключить приложения аналитики",
|
||||
"connect_other_apps": "Подключить другие приложения",
|
||||
"connect_web3_apps": "Подключить приложения web3",
|
||||
"connect_messaging_apps": "Подключить мессенджеры",
|
||||
"connect_crm_apps": "Подключить CRM-приложения",
|
||||
"current_step_of_total": "Шаг {{currentStep}} из {{maxSteps}}",
|
||||
"add_variable": "Добавить переменную",
|
||||
"custom_phone_number": "Номер телефона для отправки уведомлений",
|
||||
@@ -1247,12 +1319,14 @@
|
||||
"location_info": "Место проведения события",
|
||||
"additional_notes_info": "Дополнительные заметки о бронировании",
|
||||
"attendee_name_info": "Участник, на которого оформляется бронирование",
|
||||
"organizer_name_info": "Имя организатора",
|
||||
"to": "Кому",
|
||||
"workflow_turned_on_successfully": "Состояние рабочего процесса «{{workflowName}}» изменено на «{{offOn}}»",
|
||||
"download_responses": "Скачать ответы",
|
||||
"download_responses_description": "Скачать все ответы пользователей, заполнивших форму, в формате CSV.",
|
||||
"download": "Скачать",
|
||||
"download_recording": "Скачать запись",
|
||||
"recording_from_your_recent_call": "Запись вашего недавнего созвана в {{appName}} готова для скачивания",
|
||||
"create_your_first_form": "Создайте первую форму",
|
||||
"create_your_first_form_description": "Формы маршрутизации позволяют задавать пользователям уточняющие вопросы, чтобы перенаправлять их к соответствующему лицу или типу события.",
|
||||
"create_your_first_webhook": "Создайте свой первый вебхук",
|
||||
@@ -1261,7 +1335,9 @@
|
||||
"event_one": "событие",
|
||||
"event_other": "событий",
|
||||
"profile_team_description": "Настройка профиля вашей команды",
|
||||
"profile_org_description": "Настроить профиль организации",
|
||||
"members_team_description": "Пользователи, входящие в группу",
|
||||
"organization_description": "Управляйте администраторами и сотрудниками вашей организации",
|
||||
"team_url": "URL-адрес команды",
|
||||
"team_members": "Участники команды",
|
||||
"more": "Еще",
|
||||
@@ -1302,6 +1378,7 @@
|
||||
"routing_forms_send_email_owner": "Отправляйте письма владельцу",
|
||||
"routing_forms_send_email_owner_description": "Отправляйте владельцу формы электронное письмо, когда пользователь ее заполняет",
|
||||
"add_new_form": "Добавить новую форму",
|
||||
"add_new_team_form": "Добавить новую форму в команду",
|
||||
"create_your_first_route": "Создайте первый маршрут",
|
||||
"route_to_the_right_person": "Перенаправляйте клиентов к нужному участнику команды исходя из ответов при заполнении формы",
|
||||
"form_description": "Создайте форму для перенаправления пользователей при бронировании",
|
||||
@@ -1387,6 +1464,7 @@
|
||||
"new_event_type_availability": "{{eventTypeTitle}} | Доступность",
|
||||
"error_editing_availability": "Ошибка при редактировании доступности",
|
||||
"dont_have_permission": "У вас нет разрешения на доступ к этому ресурсу.",
|
||||
"saml_config": "SAML",
|
||||
"saml_configuration_placeholder": "Пожалуйста, вставьте здесь метаданные SAML от вашего провайдера",
|
||||
"saml_email_required": "Пожалуйста, введите адрес электронной почты, чтобы мы могли найти ваш SAML идентификатор провайдера",
|
||||
"saml_sp_title": "Детали поставщика услуг",
|
||||
@@ -1405,15 +1483,19 @@
|
||||
"yearly": "Ежегодная",
|
||||
"checkout": "Оплатить заказ",
|
||||
"your_team_disbanded_successfully": "Ваша команда расформирована",
|
||||
"your_org_disbanded_successfully": "Ваша организация расформирована",
|
||||
"error_creating_team": "Ошибка при создании команды",
|
||||
"you": "Вы",
|
||||
"resend_email": "Отправить письмо еще раз",
|
||||
"member_already_invited": "Участник уже приглашен",
|
||||
"enter_email_or_username": "Введите адрес электронной почты или имя пользователя",
|
||||
"team_name_taken": "Это название уже занято",
|
||||
"must_enter_team_name": "Необходимо ввести название команды",
|
||||
"team_url_required": "Необходимо ввести URL-адрес команды",
|
||||
"url_taken": "Этот URL-адрес уже занят",
|
||||
"problem_registering_domain": "Возникла проблема с регистрацией поддомена. Попробуйте еще раз или свяжитесь с администратором",
|
||||
"team_publish": "Опубликовать команду",
|
||||
"number_text_notifications": "Номер телефона (SMS-уведомления)",
|
||||
"attendee_email_variable": "Электронная почта участника",
|
||||
"attendee_email_info": "Электронная почта участника, на которого оформляется бронирование",
|
||||
"kbar_search_placeholder": "Введите команду или начните поиск...",
|
||||
@@ -1436,6 +1518,8 @@
|
||||
"find_the_best_person": "Выбирайте наиболее подходящего сотрудника из команды в порядке очередности.",
|
||||
"fixed_round_robin": "Фиксированная очередность",
|
||||
"add_one_fixed_attendee": "Добавьте одного фиксированного участника и назначайте участников по очереди.",
|
||||
"calcom_is_better_with_team": "{{appName}} отлично подходит для командной работы",
|
||||
"the_calcom_team": "Команда {{companyName}}",
|
||||
"add_your_team_members": "Добавьте участников команды к типам мероприятий. Благодаря совместному планированию можно включить в мероприятие всех пользователей или найти наиболее подходящего пользователя с циклическим планированием.",
|
||||
"booking_limit_reached": "Достигнут лимит бронирования для этого типа события",
|
||||
"duration_limit_reached": "Достигнут лимит продолжительности бронирования для этого типа события",
|
||||
@@ -1454,6 +1538,7 @@
|
||||
"navigate_installed_apps": "Перейти к установленным приложениям",
|
||||
"disabled_calendar": "Если у вас установлен другой календарь, в него будут добавляться новые бронирования. Если у вас нет установленного календаря, подключите новый календарь, чтобы не пропускать новые бронирования.",
|
||||
"enable_apps": "Включить приложения",
|
||||
"enable_apps_description": "Выберите приложения, которые пользователи могут интегрировать с {{appName}}",
|
||||
"purchase_license": "Купить лицензию",
|
||||
"already_have_key": "У меня уже есть ключ:",
|
||||
"already_have_key_suggestion": "Скопируйте сюда переменную окружения CALCOM_LICENSE_KEY.",
|
||||
@@ -1467,6 +1552,9 @@
|
||||
"no_available_apps": "Нет доступных приложений",
|
||||
"no_available_apps_description": "Убедитесь, что в вашей установке в 'packages/app-store' есть приложения",
|
||||
"no_apps": "В этом экземпляре Cal нет включенных приложений",
|
||||
"no_apps_configured": "Нет настроенных приложений",
|
||||
"enable_in_settings": "Выберите приложения в настройках",
|
||||
"please_contact_admin": "Свяжитесь с вашим администратором",
|
||||
"apps_settings": "Настройки приложений",
|
||||
"fill_this_field": "Заполните это поле",
|
||||
"options": "Настройки",
|
||||
@@ -1573,6 +1661,7 @@
|
||||
"email_no_user_invite_heading": "Вас пригласили в {{appName}} {{entity}}",
|
||||
"email_no_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в команду в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.",
|
||||
"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_two": "Подключите аккаунт календаря",
|
||||
"email_no_user_step_three": "Задайте время, в которое вы доступны",
|
||||
@@ -1584,6 +1673,7 @@
|
||||
"no_workflows": "Нет рабочих процессов",
|
||||
"change_filter": "Измените фильтр, чтобы видеть свои рабочие процессы и рабочие процессы своей команды.",
|
||||
"change_filter_common": "Измените фильтр, чтобы увидеть результаты.",
|
||||
"no_results_for_filter": "Поиск с заданным фильтром не дал результатов",
|
||||
"recommended_next_steps": "Рекомендуемые следующие шаги",
|
||||
"create_a_managed_event": "Создайте тип событий, которыми вы будете управлять",
|
||||
"meetings_are_better_with_the_right": "Встречи проходят эффективнее, когда на них присутствуют подходящие участники команды. Пригласите их сейчас.",
|
||||
@@ -1594,6 +1684,7 @@
|
||||
"no_longer_attending": "Вы отказались от посещения этого мероприятия",
|
||||
"attendee_no_longer_attending_subject": "Участник отказался от посещения мероприятия {{title}} в {{date}}",
|
||||
"attendee_no_longer_attending": "Участник отказался от посещения вашего мероприятия",
|
||||
"attendee_no_longer_attending_subtitle": "{{name}} отказался(-ась) от посещения мероприятия. Этот промежуток времени снова свободен",
|
||||
"create_event_on": "Создать событие в календаре",
|
||||
"create_routing_form_on": "Создать форму маршрутизации",
|
||||
"default_app_link_title": "Установить ссылку на приложение по умолчанию",
|
||||
@@ -1605,6 +1696,7 @@
|
||||
"booking_questions_title": "Вопросы при бронировании",
|
||||
"booking_questions_description": "Настройка вопросов, задаваемых пользователю на странице бронирования",
|
||||
"add_a_booking_question": "Добавить вопрос",
|
||||
"identifier": "Идентификатор",
|
||||
"duplicate_email": "Адрес электронной почты уже существует",
|
||||
"booking_with_payment_cancelled": "Оплата этого события больше невозможна",
|
||||
"booking_with_payment_cancelled_already_paid": "Выполняется возврат оплаты за бронирование.",
|
||||
@@ -1645,13 +1737,16 @@
|
||||
"spot_popular_event_types": "Определяйте наиболее популярные типы событий",
|
||||
"spot_popular_event_types_description": "Узнайте, какие типы событий собирают больше всего кликов и бронирований",
|
||||
"no_responses_yet": "Ответов пока нет",
|
||||
"no_routes_defined": "Маршруты не определены",
|
||||
"this_will_be_the_placeholder": "Это текст-заполнитель",
|
||||
"error_booking_event": "При бронировании события произошла ошибка. Обновите страницу и повторите попытку",
|
||||
"timeslot_missing_title": "Не выбран интервал времени",
|
||||
"timeslot_missing_description": "Чтобы забронировать событие, выберите интервал времени.",
|
||||
"timeslot_missing_cta": "Выбрать интервал времени",
|
||||
"switch_monthly": "Перейти в режим «месяц»",
|
||||
"switch_weekly": "Перейти в режим «неделя»",
|
||||
"switch_multiday": "Перейти в режим «день»",
|
||||
"switch_columnview": "Перейти в режим «столбцы»",
|
||||
"num_locations": "Варианты местоположений: {{num}}",
|
||||
"select_on_next_step": "Выбрать на следующем этапе",
|
||||
"this_meeting_has_not_started_yet": "Эта встреча еще не началась",
|
||||
@@ -1706,12 +1801,14 @@
|
||||
"least_booked_members": "Участники с наименьшим числом бронирований",
|
||||
"events_created": "Созданные события",
|
||||
"events_completed": "Завершенные события",
|
||||
"events_cancelled": "Отмененные события",
|
||||
"events_rescheduled": "Перенесенные события",
|
||||
"from_last_period": "с последнего периода",
|
||||
"from_to_date_period": "С: {{startDate}} По: {{endDate}}",
|
||||
"redirect_url_warning": "При использовании перенаправления страница успешного бронирования будет отключена. Не забудьте упомянуть «Бронирование подтверждено» на собственной странице оповещения об успешном бронировании.",
|
||||
"event_trends": "Тренды событий",
|
||||
"clear_filters": "Сбросить фильтры",
|
||||
"clear": "Очистить",
|
||||
"hold": "Заморозить",
|
||||
"on_booking_option": "Списывать оплату при бронировании",
|
||||
"hold_option": "Взимать комиссию за неявку",
|
||||
@@ -1738,7 +1835,18 @@
|
||||
"complete_your_booking": "Завершить бронирование",
|
||||
"complete_your_booking_subject": "Завершите бронирование: {{title}}, {{date}}",
|
||||
"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}}",
|
||||
"charge_card_dialog_body": "Вы собираетесь списать с участника {{amount, currency}}. Продолжить?",
|
||||
"charge_attendee": "Списать с участника {{amount, currency}}",
|
||||
@@ -1747,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "Приглашено пользователей: {{userCount}}",
|
||||
"error_collecting_card": "Ошибка при обработке карты",
|
||||
"image_size_limit_exceed": "Размер загружаемого изображения не должен превышать 5 МБ",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}: У вас нет права включать или отключать этот рабочий процесс",
|
||||
"inline_embed": "Встраивание в содержимое сайта",
|
||||
"load_inline_content": "Отображение события вместе с другим содержимым сайта.",
|
||||
"floating_pop_up_button": "Плавающая кнопка",
|
||||
@@ -1768,6 +1877,67 @@
|
||||
"first_event_type_webhook_description": "Создайте первый вебхук для этого типа событий",
|
||||
"install_app_on": "Установить приложение на",
|
||||
"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": "Направьте запрос в команду и начните составлять расписания вместе",
|
||||
"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": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавьте строки выше ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
"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.",
|
||||
"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_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.",
|
||||
@@ -129,6 +130,7 @@
|
||||
"upgrade_banner_action": "Buradan yükseltin",
|
||||
"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_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",
|
||||
"hey_there": "Selam,",
|
||||
"forgot_your_password_calcom": "Şifrenizi mi unuttunuz? - {{appName}}",
|
||||
@@ -503,6 +505,7 @@
|
||||
"additional_guests": "Misafir ekle",
|
||||
"your_name": "Adınız",
|
||||
"your_full_name": "Tam adınız",
|
||||
"no_name": "Ad yok",
|
||||
"email_address": "E-posta adresi",
|
||||
"enter_valid_email": "Lütfen geçerli bir e-posta adresi girin",
|
||||
"location": "Konum",
|
||||
@@ -546,6 +549,7 @@
|
||||
"your_team_updated_successfully": "Ekibiniz başarıyla güncellendi.",
|
||||
"about": "Hakkında",
|
||||
"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",
|
||||
"organization_members": "Kuruluş üyeleri",
|
||||
"member": "Üye",
|
||||
@@ -582,6 +586,7 @@
|
||||
"confirm_all": "Tümünü onayla",
|
||||
"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_org": "Kuruluşu Dağıt",
|
||||
"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?",
|
||||
"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_deleted_successfully": "Etkinlik türü başarıyla silindi",
|
||||
"hours": "Saat",
|
||||
"people": "İnsan",
|
||||
"your_email": "E-postanız",
|
||||
"change_avatar": "Avatarı değiştir",
|
||||
"language": "Dil",
|
||||
@@ -689,9 +695,11 @@
|
||||
"create_new_team": "Yeni ekip oluştur",
|
||||
"open_invitations": "Açık Davetler",
|
||||
"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",
|
||||
"teams": "Ekipler",
|
||||
"team": "Ekip",
|
||||
"organization": "Kuruluş",
|
||||
"team_billing": "Ekip Faturası",
|
||||
"team_billing_description": "Ekibiniz için faturalandırmayı yönetin",
|
||||
"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_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",
|
||||
"you_need_to_add_a_name": "Bir ad eklemeniz gerekiyor",
|
||||
"commission_per_transaction": "işlem başına komisyon",
|
||||
"event_type_updated_successfully_description": "Etkinlik türünüz başarıyla güncellendi.",
|
||||
"hide_event_type": "Etkinlik türünü gizle",
|
||||
@@ -856,18 +865,25 @@
|
||||
"installed_apps": "Yüklü Uygulamalar",
|
||||
"free_to_use_apps": "Ücretsiz",
|
||||
"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_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_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_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_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_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_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_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",
|
||||
"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.",
|
||||
@@ -893,6 +909,7 @@
|
||||
"create_events_on": "Şurada etkinlik oluşturun:",
|
||||
"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_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",
|
||||
"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.",
|
||||
@@ -962,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Bu API anahtarını iptal et",
|
||||
"revoke_api_key": "API anahtarını iptal et",
|
||||
"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ı?",
|
||||
"copy": "Kopyala",
|
||||
"expire_date": "Son tarih",
|
||||
@@ -984,6 +1002,9 @@
|
||||
"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.",
|
||||
"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",
|
||||
"impersonate_user_tip": "Bu özelliğin tüm kullanımları denetlenir.",
|
||||
"impersonating_user_warning": "\"{{user}}\" kullanıcı adı kimliğine bürünme.",
|
||||
@@ -1051,16 +1072,21 @@
|
||||
"event_location": "Etkinliğin konumu",
|
||||
"reschedule_optional": "Yeniden planlama nedeni (isteğe bağlı)",
|
||||
"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.",
|
||||
"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",
|
||||
"url_start_with_https": "URL'nin http:// veya https:// ile başlaması gerekiyor",
|
||||
"number_provided": "Telefon numarası sağlanacaktır",
|
||||
"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",
|
||||
"email_host_action": "organizatöre 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",
|
||||
"whatsapp_number_action": "belirli bir numaraya Whatsapp mesajı gönder",
|
||||
"whatsapp_attendee_action": "katılımcıya Whatsapp mesajı gönder",
|
||||
"workflows": "İş akışları",
|
||||
"new_workflow_btn": "Yeni İş Akışı",
|
||||
"add_new_workflow": "Yeni iş akışı ekle",
|
||||
@@ -1124,6 +1150,8 @@
|
||||
"choose_template": "Bir şablon seçin",
|
||||
"custom": "Özel",
|
||||
"reminder": "Hatırlatıcı",
|
||||
"rescheduled": "Yeniden planlandı",
|
||||
"completed": "Tamamlandı",
|
||||
"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.",
|
||||
"minute_one": "{{count}} dakika",
|
||||
@@ -1221,6 +1249,7 @@
|
||||
"start_of_week": "Haftanın başlangıcı",
|
||||
"recordings_title": "Kayıtlar",
|
||||
"recording": "Kayıt",
|
||||
"happy_scheduling": "İyi planlamalar",
|
||||
"select_calendars": "Çifte rezervasyonu önlemek için çakışmaları kontrol etmek istediğiniz takvimleri seçin.",
|
||||
"check_for_conflicts": "Çakışmaları kontrol edin",
|
||||
"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",
|
||||
"add_conferencing_app": "Konferans Uygulaması ekle",
|
||||
"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.",
|
||||
"skip": "Atla",
|
||||
"do_this_later": "Bunu daha sonra yap",
|
||||
@@ -1275,6 +1305,8 @@
|
||||
"connect_analytics_apps": "Analiz uygulamaları bağlayın",
|
||||
"connect_other_apps": "Diğer uygulamaları 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",
|
||||
"add_variable": "Değişken ekle",
|
||||
"custom_phone_number": "Özel telefon numarası",
|
||||
@@ -1287,12 +1319,14 @@
|
||||
"location_info": "Etkinlik yeri",
|
||||
"additional_notes_info": "Ek rezervasyon notları",
|
||||
"attendee_name_info": "Rezervasyon yaptıran kişinin adı",
|
||||
"organizer_name_info": "Düzenleyenin adı",
|
||||
"to": "Kime",
|
||||
"workflow_turned_on_successfully": "{{workflowName}} iş akışı başarıyla {{offOn}} hale getirildi",
|
||||
"download_responses": "Yanıtları İndir",
|
||||
"download_responses_description": "Formunuza gelen tüm yanıtları CSV formatında indirin.",
|
||||
"download": "İ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_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",
|
||||
@@ -1301,7 +1335,9 @@
|
||||
"event_one": "etkinlik",
|
||||
"event_other": "etkinlik",
|
||||
"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",
|
||||
"organization_description": "Kuruluşunuzdaki yöneticileri ve üyeleri yönetin",
|
||||
"team_url": "Ekip URL'si",
|
||||
"team_members": "Ekip üyeleri",
|
||||
"more": "Daha fazla",
|
||||
@@ -1342,6 +1378,7 @@
|
||||
"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",
|
||||
"add_new_form": "Yeni form ekle",
|
||||
"add_new_team_form": "Ekibinize yeni bir form ekleyin",
|
||||
"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",
|
||||
"form_description": "Rezervasyon yapan kişiyi yönlendirmek için formunuzu oluşturun",
|
||||
@@ -1446,6 +1483,7 @@
|
||||
"yearly": "Yıllık",
|
||||
"checkout": "Ödeme yap",
|
||||
"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",
|
||||
"you": "Siz",
|
||||
"resend_email": "E-postayı tekrar gönder",
|
||||
@@ -1455,6 +1493,7 @@
|
||||
"must_enter_team_name": "Ekip adı girilmelidir",
|
||||
"team_url_required": "Ekip URL'si girilmelidir",
|
||||
"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",
|
||||
"number_text_notifications": "Telefon numarası (SMS bildirimleri)",
|
||||
"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.",
|
||||
"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.",
|
||||
"calcom_is_better_with_team": "{{appName}}, ekiplerle daha iyidir",
|
||||
"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.",
|
||||
"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",
|
||||
"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_description": "Kullanıcıların {{appName}} ile entegre edebileceği uygulamaları etkinleştirin",
|
||||
"purchase_license": "Lisans satın alın",
|
||||
"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.",
|
||||
@@ -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.",
|
||||
"organizer_timezone": "Organizatörün saat dilimi",
|
||||
"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_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_two": "Takvim hesabınızı bağlayın",
|
||||
"email_no_user_step_three": "Müsaitlik durumunuzu ayarlayın",
|
||||
@@ -1628,6 +1672,7 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"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_common": "Sonuçları görmek için filtreyi değiştirin.",
|
||||
"no_results_for_filter": "Filtre için hiçbir sonuç bulunamadı",
|
||||
"recommended_next_steps": "Önerilen sonraki adımlar",
|
||||
"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_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_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_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ı",
|
||||
@@ -1650,6 +1696,7 @@
|
||||
"booking_questions_title": "Rezervasyon soruları",
|
||||
"booking_questions_description": "Rezervasyon sayfasında sorulan soruları özelleştirin",
|
||||
"add_a_booking_question": "Soru ekle",
|
||||
"identifier": "Tanımlayıcı",
|
||||
"duplicate_email": "E-posta yinelenmiş",
|
||||
"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.",
|
||||
@@ -1660,6 +1707,7 @@
|
||||
"show_on_booking_page": "Rezervasyon sayfasında göster",
|
||||
"get_started_zapier_templates": "Zapier şablonlarını kullanmaya başlayın",
|
||||
"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",
|
||||
"a_routing_form": "Yönlendirme Formu",
|
||||
"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_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_routes_defined": "Yönlendirmeler tanımlanmadı",
|
||||
"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",
|
||||
"timeslot_missing_title": "Zaman aralığı seçilmedi",
|
||||
@@ -1697,6 +1746,7 @@
|
||||
"switch_monthly": "Aylı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_columnview": "Sütun görünümüne geç",
|
||||
"num_locations": "{{num}} konum seçeneği",
|
||||
"select_on_next_step": "Bir sonraki adımda seç",
|
||||
"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_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_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.",
|
||||
"review_event_type": "Etkinlik Türünü inceleyin",
|
||||
"looking_for_more_analytics": "Daha fazla analiz mi arıyorsunuz?",
|
||||
@@ -1789,11 +1840,13 @@
|
||||
"invite_link_copied": "Davet bağlantısı kopyalandı",
|
||||
"invite_link_deleted": "Davet bağlantısı silindi",
|
||||
"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",
|
||||
"seven_days": "7 gün",
|
||||
"thirty_days": "30 gün",
|
||||
"three_months": "3 ay",
|
||||
"one_year": "1 yıl",
|
||||
"team_invite_received": "{{teamName}} ekibine katılmaya davet edildiniz",
|
||||
"currency_string": "{{amount, currency}}",
|
||||
"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",
|
||||
@@ -1802,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "{{userCount}} kullanıcı davet edildi",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1821,8 +1875,13 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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_admin_email": "Kuruluşunuzun e-posta adresini girmelisiniz",
|
||||
"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.",
|
||||
"additional_url_parameters": "Ek URL parametreleri",
|
||||
"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_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_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_settings": "Ayarlarım",
|
||||
"crm": "CRM",
|
||||
"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.",
|
||||
"org_name": "Kuruluş adı",
|
||||
"org_url": "Kuruluş URL'si",
|
||||
"copy_link_org": "Bağlantıyı kuruluşa kopyala",
|
||||
"404_the_org": "Kuruluş",
|
||||
"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_team_filter": "Ekip: {{teamName}}",
|
||||
"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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -18,12 +18,16 @@
|
||||
"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_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_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_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",
|
||||
"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_placeholder": "Lý do bạn muốn hủy?",
|
||||
"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",
|
||||
"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",
|
||||
"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_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}}",
|
||||
"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}}",
|
||||
@@ -124,6 +130,7 @@
|
||||
"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!",
|
||||
"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",
|
||||
"hey_there": "Xin chào,",
|
||||
"forgot_your_password_calcom": "Quên mật khẩu của bạn? - {{appName}}",
|
||||
@@ -190,6 +197,7 @@
|
||||
"blog": "Blog",
|
||||
"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_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",
|
||||
"popular_pages": "Các trang phổ biến",
|
||||
"register_now": "Đăng ký ngay",
|
||||
@@ -197,6 +205,7 @@
|
||||
"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.",
|
||||
"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",
|
||||
"15min_meeting": "Cuộc họp 15 phút",
|
||||
"30min_meeting": "Cuộc họp 30 phút",
|
||||
@@ -232,11 +241,14 @@
|
||||
"done": "Xong",
|
||||
"all_done": "Đã xong hết!",
|
||||
"all": "Tất cả",
|
||||
"yours": "Tài khoản của bạn",
|
||||
"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.",
|
||||
"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.",
|
||||
"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": "Đặt lịch khả dụng của bạn",
|
||||
"continue_without_calendar": "Tiếp tục mà không có lịch",
|
||||
@@ -292,6 +304,18 @@
|
||||
"success": "Thành công",
|
||||
"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.",
|
||||
"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.",
|
||||
"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",
|
||||
@@ -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ờ",
|
||||
"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.",
|
||||
"cancelled": "Đã hủy",
|
||||
"cancellation_successful": "Hủy thành công",
|
||||
"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",
|
||||
@@ -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_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_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",
|
||||
"go_back_home": "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}}",
|
||||
"event_between_users": "{{eventName}} giữa {{host}} và {{attendeeName}}",
|
||||
"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.",
|
||||
"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.",
|
||||
"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_tooltip": "Lịch hẹn chưa xác nhận",
|
||||
"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",
|
||||
"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",
|
||||
"dynamic_booking": "Liên kết động cho nhóm",
|
||||
"email": "Email",
|
||||
"email_placeholder": "nvana@vidu.com",
|
||||
"full_name": "Họ và tên",
|
||||
"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.",
|
||||
"create_webhook": "Tạo Webhook",
|
||||
"booking_cancelled": "Lịch hẹn đã bị hủy",
|
||||
"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",
|
||||
"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",
|
||||
"form_submitted": "Biểu mẫu đã được gửi",
|
||||
"event_triggers": "Sự kiện kích hoạt",
|
||||
@@ -376,6 +413,8 @@
|
||||
"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",
|
||||
"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",
|
||||
"loading": "Đang tải...",
|
||||
"deleting": "Đang xóa...",
|
||||
@@ -438,6 +477,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"am_pm": "\u001dam/pm",
|
||||
"time_options": "Tùy chọn thời gian",
|
||||
@@ -465,6 +505,7 @@
|
||||
"additional_guests": "Thêm khách",
|
||||
"your_name": "Tên của bạn",
|
||||
"your_full_name": "Tên đầy đủ của bạn",
|
||||
"no_name": "Vô danh",
|
||||
"email_address": "Địa chỉ email",
|
||||
"enter_valid_email": "Vui lòng điền vào email hợp lệ",
|
||||
"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.",
|
||||
"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.",
|
||||
"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",
|
||||
"organization_members": "Thành viên trong tổ chức",
|
||||
"member": "Thành viên",
|
||||
"number_member_one": "{{count}} thành viên",
|
||||
"number_member_other": "{{count}} thành viên",
|
||||
"number_selected": "{{count}} đã chọn",
|
||||
"owner": "Chủ nhóm",
|
||||
"admin": "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ả",
|
||||
"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_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?",
|
||||
"confirm_disband_team": "Có, giải tán nhóm",
|
||||
"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_deleted_successfully": "Đã xóa thành công loại sự kiện",
|
||||
"hours": "Giờ",
|
||||
"people": "Mọi người",
|
||||
"your_email": "Email của bạn",
|
||||
"change_avatar": "Thay đổi hình đại diện",
|
||||
"language": "Ngôn ngữ",
|
||||
@@ -648,9 +695,11 @@
|
||||
"create_new_team": "Tạo một nhóm mới",
|
||||
"open_invitations": "Lời mời đang chờ",
|
||||
"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",
|
||||
"teams": "Các nhóm",
|
||||
"team": "Nhóm",
|
||||
"organization": "Tổ chức",
|
||||
"team_billing": "Thanh toán nhóm",
|
||||
"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",
|
||||
@@ -725,6 +774,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -815,18 +865,25 @@
|
||||
"installed_apps": "Ứng dụng đã cài đặt",
|
||||
"free_to_use_apps": "Miễn phí",
|
||||
"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_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_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_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_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_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_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_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",
|
||||
"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.",
|
||||
@@ -852,6 +909,7 @@
|
||||
"create_events_on": "Tạo sự kiện trên",
|
||||
"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_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",
|
||||
"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.",
|
||||
@@ -921,6 +979,7 @@
|
||||
"confirm_delete_api_key": "Thu hồi khóa API này",
|
||||
"revoke_api_key": "Thu hồi khóa API",
|
||||
"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?",
|
||||
"copy": "Sao chép",
|
||||
"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_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.",
|
||||
"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",
|
||||
"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}}\".",
|
||||
@@ -1010,16 +1072,21 @@
|
||||
"event_location": "Địa điểm sự kiệ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",
|
||||
"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.",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"email_host_action": "gửi email đến chủ sự kiện",
|
||||
"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ể",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1083,6 +1150,8 @@
|
||||
"choose_template": "Chọn mẫu",
|
||||
"custom": "Tuỳ chỉnh",
|
||||
"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}}",
|
||||
"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",
|
||||
@@ -1180,6 +1249,7 @@
|
||||
"start_of_week": "Khởi đầu tuần",
|
||||
"recordings_title": "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.",
|
||||
"check_for_conflicts": "Kiểm tra xung đột",
|
||||
"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",
|
||||
"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",
|
||||
"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.",
|
||||
"skip": "Bỏ qua",
|
||||
"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_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_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}}",
|
||||
"add_variable": "Thêm biến số",
|
||||
"custom_phone_number": "Số điện thoại tùy chỉnh",
|
||||
@@ -1246,12 +1319,14 @@
|
||||
"location_info": "Địa điểm sự kiệ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",
|
||||
"organizer_name_info": "Tên của tổ chức",
|
||||
"to": "Đến",
|
||||
"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_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_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_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",
|
||||
@@ -1260,7 +1335,9 @@
|
||||
"event_one": "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_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",
|
||||
"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_members": "Thành viên nhóm",
|
||||
"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_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_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",
|
||||
"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",
|
||||
@@ -1386,6 +1464,7 @@
|
||||
"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",
|
||||
"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_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ụ",
|
||||
@@ -1404,15 +1483,19 @@
|
||||
"yearly": "Hằng năm",
|
||||
"checkout": "Thanh toán",
|
||||
"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",
|
||||
"you": "Bạn",
|
||||
"resend_email": "Gửi lại email",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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_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...",
|
||||
@@ -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.",
|
||||
"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ự.",
|
||||
"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.",
|
||||
"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",
|
||||
@@ -1453,6 +1538,7 @@
|
||||
"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.",
|
||||
"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",
|
||||
"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.",
|
||||
@@ -1466,6 +1552,9 @@
|
||||
"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_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",
|
||||
"fill_this_field": "Vui lòng điền vào trường này",
|
||||
"options": "Tuỳ chọn",
|
||||
@@ -1571,6 +1660,8 @@
|
||||
"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_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_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",
|
||||
@@ -1581,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"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_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",
|
||||
"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.",
|
||||
@@ -1591,6 +1684,7 @@
|
||||
"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": "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_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",
|
||||
@@ -1602,6 +1696,7 @@
|
||||
"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",
|
||||
"add_a_booking_question": "Thêm một câu hỏi",
|
||||
"identifier": "Mã định danh",
|
||||
"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_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",
|
||||
"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_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",
|
||||
"a_routing_form": "Một biểu mẫu định hướng",
|
||||
"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_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_routes_defined": "Không xác định được định hướng",
|
||||
"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_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",
|
||||
"switch_monthly": "Chuyển sang giao diện tháng",
|
||||
"switch_weekly": "Chuyển sang giao diện tuần",
|
||||
"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í",
|
||||
"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",
|
||||
@@ -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_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_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ó.",
|
||||
"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?",
|
||||
@@ -1701,12 +1801,14 @@
|
||||
"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_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",
|
||||
"from_last_period": "từ thời gian gần nhất",
|
||||
"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.",
|
||||
"event_trends": "Xu hướng sự kiện",
|
||||
"clear_filters": "Xóa bộ lọc",
|
||||
"clear": "Xoá",
|
||||
"hold": "Tạm giữ",
|
||||
"on_booking_option": "Thu tiền thanh toán cho lịch hẹn",
|
||||
"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_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",
|
||||
"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}}",
|
||||
"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}}",
|
||||
@@ -1741,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "{{userCount}} người dùng đã được mời",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -1760,7 +1875,69 @@
|
||||
"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",
|
||||
"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",
|
||||
"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ể",
|
||||
"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_email_header": "验证您的电子邮件地址",
|
||||
"verify_email_email_button": "验证电子邮件",
|
||||
"copy_somewhere_safe": "将此 API 密钥保存在安全的地方。您将无法再次查看它。",
|
||||
"verify_email_email_body": "请点击下面的按钮来验证您的电子邮件地址。",
|
||||
"verify_email_email_link_text": "如果您不喜欢点击按钮,请点击以下链接:",
|
||||
"email_sent": "电子邮件已成功发送",
|
||||
@@ -243,6 +244,8 @@
|
||||
"all": "所有应用",
|
||||
"yours": "您的账户",
|
||||
"available_apps": "可用应用",
|
||||
"available_apps_lower_case": "可用的应用",
|
||||
"available_apps_desc": "您尚未安装任何应用。在我们的<1>应用商店</1>中查看热门应用,并探索更多内容。",
|
||||
"check_email_reset_password": "请检查您的邮箱,我们向您发送了一个重置密码的链接。",
|
||||
"finish": "完成",
|
||||
"organization_general_description": "管理您的团队语言和时区的设置",
|
||||
@@ -349,7 +352,7 @@
|
||||
"no_meeting_found": "未找到会议",
|
||||
"no_meeting_found_description": "此会议不存在。联系会议所有者获取更新后的链接。",
|
||||
"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}}",
|
||||
"bookings": "预约",
|
||||
"booking_not_found": "找不到预约",
|
||||
@@ -399,35 +402,36 @@
|
||||
"leverage_our_api": "利用我们的 API 来实现完全控制和高度定制。",
|
||||
"create_webhook": "创建 Webhook",
|
||||
"booking_cancelled": "预约已取消",
|
||||
"booking_rescheduled": "预约已重新安排",
|
||||
"booking_rescheduled": "预约已改期",
|
||||
"recording_ready": "录制内容下载链接就绪",
|
||||
"booking_created": "预约已创建",
|
||||
"booking_rejected": "预约被拒绝",
|
||||
"booking_requested": "预约已请求",
|
||||
"meeting_ended": "会议已结束",
|
||||
"form_submitted": "表格已提交",
|
||||
"booking_paid": "预约已付款",
|
||||
"event_triggers": "事件触发",
|
||||
"subscriber_url": "订阅者链接",
|
||||
"create_new_webhook": "创建一个新的 webhook",
|
||||
"create_new_webhook": "创建一个新的 Webhook",
|
||||
"webhooks": "Webhook",
|
||||
"team_webhooks": "团队 Webhook",
|
||||
"create_new_webhook_to_account": "为您的账户创建一个新的Webhook",
|
||||
"create_new_webhook_to_account": "为您的账户创建一个新的 Webhook",
|
||||
"new_webhook": "新建 Webhook",
|
||||
"receive_cal_meeting_data": "当安排或取消活动后,在指定链接实时接收 {{appName}} 会议数据。",
|
||||
"receive_cal_event_meeting_data": "当安排或取消此活动后,在指定链接实时接收 {{appName}} 会议数据。",
|
||||
"responsive_fullscreen_iframe": "全屏响应式iframe",
|
||||
"responsive_fullscreen_iframe": "全屏响应式 iframe",
|
||||
"loading": "加载中...",
|
||||
"deleting": "正在删除...",
|
||||
"standard_iframe": "标准 iframe",
|
||||
"developer": "开发人员",
|
||||
"manage_developer_settings": "管理您的开发人员设置。",
|
||||
"iframe_embed": "嵌入 iframe",
|
||||
"embed_calcom": "用最简单的方式将{{appName}}嵌入您的网站",
|
||||
"embed_calcom": "用最简单的方式将 {{appName}} 嵌入您的网站",
|
||||
"integrate_using_embed_or_webhooks": "将我们的功能嵌入式集成进您的网站,或者使用自定义Webhook获得实时预约信息。",
|
||||
"schedule_a_meeting": "安排会议",
|
||||
"view_and_manage_billing_details": "查看和管理您的账单详情",
|
||||
"view_and_edit_billing_details": "查看和编辑您的账单详情,以及取消订阅。",
|
||||
"go_to_billing_portal": "转到账单门户网站",
|
||||
"go_to_billing_portal": "前往付费入口",
|
||||
"need_anything_else": "还有其他需要?",
|
||||
"further_billing_help": "如果您在支付帐单时需要任何进一步的帮助,我们的支持团队会给您提供帮助。",
|
||||
"contact": "联系",
|
||||
@@ -706,8 +710,8 @@
|
||||
"upgrade_to_flexible_pro_message": "您的团队中有没有位置的成员。升级到专业版来获得更多位置。",
|
||||
"changed_team_billing_info": "自2022年1月起,我们将按每个位置向团队成员收取费用。 您的团队中免费获得专业版的成员现在正在进行为期14天的试用。 试用期结束后,这些成员将在您的团队中隐藏,除非您现在升级到专业版。",
|
||||
"create_manage_teams_collaborative": "创建并管理团队以使用协作功能。",
|
||||
"only_available_on_pro_plan": "此功能仅在Pro套餐中可用",
|
||||
"remove_cal_branding_description": "若想从您的预约页面中去掉{{appName}}品牌标志,您需要升级到专业版账户。",
|
||||
"only_available_on_pro_plan": "此功能仅在 Pro 套餐中可用",
|
||||
"remove_cal_branding_description": "若想从您的预约页面中去掉 {{appName}} 的品牌标志,您需要升级到专业版账户。",
|
||||
"edit_profile_info_description": "编辑您的个人资料,在您的预约链接上显示。",
|
||||
"change_email_tip": "您可能需要注销并重新登录才能使更改生效。",
|
||||
"little_something_about": "一些关于你自己的描述。",
|
||||
@@ -767,12 +771,12 @@
|
||||
"set_link_meeting": "设置会议链接",
|
||||
"cal_invitee_phone_number_scheduling": "{{appName}} 将要求您的受邀者在安排时间之前提供电话号码。",
|
||||
"cal_provide_google_meet_location": "{{appName}} 将提供 Google Meet 位置。",
|
||||
"cal_provide_zoom_meeting_url": "{{appName}}将提供Zoom会议链接",
|
||||
"cal_provide_tandem_meeting_url": "{{appName}} 将提供Tandem会议链接",
|
||||
"cal_provide_video_meeting_url": "{{appName}}将提供Daily视频会议链接",
|
||||
"cal_provide_jitsi_meeting_url": "{{appName}} 将提供Jitsi Meet视频会议链接",
|
||||
"cal_provide_huddle01_meeting_url": "{{appName}} 将提供Huddle01 Web3视频会议链接",
|
||||
"cal_provide_teams_meeting_url": "{{appName}} 将提供 MS Teams 会议 URL。注意: 必须拥有工作或学校帐户",
|
||||
"cal_provide_zoom_meeting_url": "{{appName}}将提供 Zoom 会议链接",
|
||||
"cal_provide_tandem_meeting_url": "{{appName}} 将提供 Tandem 会议链接",
|
||||
"cal_provide_video_meeting_url": "{{appName}}将提供 Daily 视频会议链接",
|
||||
"cal_provide_jitsi_meeting_url": "{{appName}} 将提供 Jitsi Meet 视频会议链接",
|
||||
"cal_provide_huddle01_meeting_url": "{{appName}} 将提供 Huddle01 web3 视频会议链接",
|
||||
"cal_provide_teams_meeting_url": "{{appName}} 将提供 MS Teams 会议 URL。注意: 须拥有工作或学校帐户",
|
||||
"require_payment": "需要付款",
|
||||
"you_need_to_add_a_name": "您需要添加名称",
|
||||
"commission_per_transaction": "每笔交易的佣金",
|
||||
@@ -846,7 +850,7 @@
|
||||
"user_away_description": "您试图预约的人已将自己置于离开状态,因此不接受新预约。",
|
||||
"meet_people_with_the_same_tokens": "会见使用相同令牌的人",
|
||||
"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_description": "要更改您的电子邮件,密码,启用两步验证及更多功能,请访问您的 {{provider}} 账户设置。",
|
||||
"signin_with_google": "使用Google登录",
|
||||
@@ -1465,8 +1469,8 @@
|
||||
"error_editing_availability": "编辑可预约时间时出错",
|
||||
"dont_have_permission": "您无权访问此资源。",
|
||||
"saml_config": "SAML",
|
||||
"saml_configuration_placeholder": "请将从身份提供商获取的 SAML metadata 粘贴到这里",
|
||||
"saml_email_required": "请输入您的邮箱,以便我们找到您的 SAML 身份提供商",
|
||||
"saml_configuration_placeholder": "请将从身份提供方获取的 SAML metadata 粘贴到这里",
|
||||
"saml_email_required": "请输入您的邮箱,以便我们找到您的 SAML 身份提供方",
|
||||
"saml_sp_title": "服务提供商详细信息",
|
||||
"saml_sp_description": "您的身份提供程序 (IdP) 将要求您提供以下详细信息以完成 SAML 应用程序配置。",
|
||||
"saml_sp_acs_url": "ACS 链接",
|
||||
@@ -1939,5 +1943,5 @@
|
||||
"insights_user_filter": "用户:{{userName}}",
|
||||
"insights_subtitle": "查看您的活动的预约洞察",
|
||||
"custom_plan": "自定义计划",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在上面这里添加新的字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在此上方添加您的新字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"identity_provider": "身分提供者",
|
||||
"trial_days_left": "試用 PRO 方案還有 $t(day, {\"count\": {{days}} })",
|
||||
"trial_days_left": "您的 PRO 試用期還有 $t(day, {\"count\": {{days}} }) 到期",
|
||||
"day_one": "{{count}} 天",
|
||||
"day_other": "{{count}} 天",
|
||||
"second_one": "{{count}} 秒",
|
||||
@@ -306,9 +306,9 @@
|
||||
"password_has_been_reset_login": "密碼已經重置。現在即可使用新建立的密碼登入。",
|
||||
"layout": "版面",
|
||||
"bookerlayout_default_title": "預設檢視",
|
||||
"bookerlayout_description": "您可以選擇多個版面,以便您的預約者切換檢視。",
|
||||
"bookerlayout_description": "您可以選擇多個版面,以便預約者切換檢視。",
|
||||
"bookerlayout_user_settings_title": "預約版面",
|
||||
"bookerlayout_user_settings_description": "您可以選擇多個版面,以便您的預約者切換檢視。您可根據不同活動來覆寫此設定。",
|
||||
"bookerlayout_user_settings_description": "您可以選擇多個版面,以便預約者切換檢視。您可根據不同活動來覆寫此設定。",
|
||||
"bookerlayout_month_view": "月",
|
||||
"bookerlayout_week_view": "週",
|
||||
"bookerlayout_column_view": "欄",
|
||||
@@ -349,7 +349,7 @@
|
||||
"no_meeting_found": "找不到會議",
|
||||
"no_meeting_found_description": "會議不存在。請聯繫會議主持人取得新連結。",
|
||||
"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}}",
|
||||
"bookings": "預約",
|
||||
"booking_not_found": "找不到預約",
|
||||
@@ -398,7 +398,7 @@
|
||||
"browse_api_documentation": "瀏覽 API 文件",
|
||||
"leverage_our_api": "請充分利用 API 徹底掌握與客製化。",
|
||||
"create_webhook": "建立 Webhook",
|
||||
"booking_cancelled": "預約已取消",
|
||||
"booking_cancelled": "已取消預約",
|
||||
"booking_rescheduled": "已重新安排預約",
|
||||
"recording_ready": "錄製內容下載連結已就緒",
|
||||
"booking_created": "已建立預約",
|
||||
@@ -411,17 +411,17 @@
|
||||
"create_new_webhook": "建立新的 Webhook",
|
||||
"webhooks": "Webhook",
|
||||
"team_webhooks": "團隊 Webhook",
|
||||
"create_new_webhook_to_account": "建立這個帳號的新 Webhook",
|
||||
"create_new_webhook_to_account": "為您的帳號建立一個的新 Webhook",
|
||||
"new_webhook": "新 Webhook",
|
||||
"receive_cal_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。",
|
||||
"receive_cal_event_meeting_data": "預定或取消活動時,即時在指定的網址收到 {{appName}} 會議資料。",
|
||||
"responsive_fullscreen_iframe": "全螢幕響應式 Iframe",
|
||||
"responsive_fullscreen_iframe": "全螢幕響應式 iframe",
|
||||
"loading": "讀取中...",
|
||||
"deleting": "正在刪除......",
|
||||
"standard_iframe": "標準 Iframe",
|
||||
"standard_iframe": "標準 iframe",
|
||||
"developer": "開發人員",
|
||||
"manage_developer_settings": "管理您的開發人員設定。",
|
||||
"iframe_embed": "嵌入式 Iframe",
|
||||
"iframe_embed": "嵌入式 iframe",
|
||||
"embed_calcom": "在網站上嵌入 {{appName}} 最簡單的方法。",
|
||||
"integrate_using_embed_or_webhooks": "使用嵌入的方法整合進網站,或是以自訂 Webhook 的方式獲取即時預約資訊。",
|
||||
"schedule_a_meeting": "預定會議",
|
||||
@@ -846,7 +846,7 @@
|
||||
"user_away_description": "試圖預約的人已經設定為離開狀態,因此不接受新預約。",
|
||||
"meet_people_with_the_same_tokens": "認識有相同 Token 的人",
|
||||
"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_description": "要更改電子郵件、密碼、兩階段認證⋯⋯等,請造訪 {{provider}} 的帳號設定。",
|
||||
"signin_with_google": "透過 Google 登入",
|
||||
@@ -979,7 +979,7 @@
|
||||
"confirm_delete_api_key": "撤銷此 API 金鑰",
|
||||
"revoke_api_key": "撤銷 API 金鑰",
|
||||
"api_key_copied": "已複製 API 金鑰!",
|
||||
"api_key_expires_on": "API 金鑰的到期時間為",
|
||||
"api_key_expires_on": "API 金鑰的到期時間",
|
||||
"delete_api_key_confirm_title": "確定要將此 API 金鑰從您的帳號永久移除?",
|
||||
"copy": "複製",
|
||||
"expire_date": "到期日",
|
||||
@@ -1003,7 +1003,7 @@
|
||||
"user_impersonation_description": "允許支援團隊以您的身分暫時登入,以便快速解決您通報給我們的任何問題。",
|
||||
"team_impersonation_description": "允許您的團隊擁有者/管理員暫時以您的身分登入。",
|
||||
"make_team_private": "設為私人團隊",
|
||||
"make_team_private_description": "啟用此設定時,您的團隊成員將無法查看其他團隊成員。",
|
||||
"make_team_private_description": "啟用此設定時,團隊成員將無法查看其他團隊成員。",
|
||||
"you_cannot_see_team_members": "您無法查看私人團隊的所有團隊成員。",
|
||||
"allow_booker_to_select_duration": "允許預約者選擇時間長度",
|
||||
"impersonate_user_tip": "此功能的所有使用已經過稽核。",
|
||||
@@ -1291,7 +1291,7 @@
|
||||
"conferencing_description": "為您的會議加入最愛的視訊會議應用程式",
|
||||
"add_conferencing_app": "新增會議應用程式",
|
||||
"password_description": "管理帳號密碼設定",
|
||||
"set_up_two_factor_authentication": "設定您的兩階段驗證",
|
||||
"set_up_two_factor_authentication": "設定兩階段驗證",
|
||||
"we_just_need_basic_info": "我們只需要一些基本資料,就能完成您的個人資料設定。",
|
||||
"skip": "略過",
|
||||
"do_this_later": "稍後再說",
|
||||
@@ -1335,7 +1335,7 @@
|
||||
"event_one": "活動",
|
||||
"event_other": "活動",
|
||||
"profile_team_description": "管理團隊資料設定",
|
||||
"profile_org_description": "管理您的組織資料設定",
|
||||
"profile_org_description": "管理組織資料設定",
|
||||
"members_team_description": "群組中的使用者",
|
||||
"organization_description": "管理您組織的管理者和成員",
|
||||
"team_url": "團隊網址",
|
||||
@@ -1378,7 +1378,7 @@
|
||||
"routing_forms_send_email_owner": "傳送電子郵件給擁有者",
|
||||
"routing_forms_send_email_owner_description": "表單提交後傳送電子郵件給擁有者",
|
||||
"add_new_form": "新增新表單",
|
||||
"add_new_team_form": "為您的團隊新增表單",
|
||||
"add_new_team_form": "為團隊新增表單",
|
||||
"create_your_first_route": "建立第一份引導表單",
|
||||
"route_to_the_right_person": "根據表單回覆引導至合適的人員",
|
||||
"form_description": "建立您的表單來引導預約者",
|
||||
@@ -1465,8 +1465,8 @@
|
||||
"error_editing_availability": "編輯開放時間時發生錯誤",
|
||||
"dont_have_permission": "您沒有權限存取此資源。",
|
||||
"saml_config": "SAML",
|
||||
"saml_configuration_placeholder": "請把 Identity Provider 的 SAML Metadata 貼到這裡。",
|
||||
"saml_email_required": "請輸入讓我們可以找到 SAML Identity Provider 的電子郵件",
|
||||
"saml_configuration_placeholder": "請把身分提供者的 SAML Metadata 貼到這裡。",
|
||||
"saml_email_required": "請輸入讓我們可以找到 SAML 身分提供者的電子郵件",
|
||||
"saml_sp_title": "服務供應方詳細資訊",
|
||||
"saml_sp_description": "您的 Identity Provider (IdP) 會要求您提供下列詳細資料,以完成 SAML 應用程式設定。",
|
||||
"saml_sp_acs_url": "ACS 網址",
|
||||
@@ -1672,6 +1672,8 @@
|
||||
"scheduler": "{Scheduler}",
|
||||
"no_workflows": "無工作流程",
|
||||
"change_filter": "變更篩選條件,即可查看您個人和團隊的工作流程。",
|
||||
"change_filter_common": "變更篩選條件以查看結果。",
|
||||
"no_results_for_filter": "此篩選條件找不到結果",
|
||||
"recommended_next_steps": "建議的後續步驟",
|
||||
"create_a_managed_event": "建立受管活動類型",
|
||||
"meetings_are_better_with_the_right": "找對團隊成員開會,開會更有效率。立即邀請他們。",
|
||||
@@ -1682,7 +1684,9 @@
|
||||
"no_longer_attending": "您不再參加這個活動",
|
||||
"attendee_no_longer_attending_subject": "一位與會者不再參加 {{date}} 的 {{title}}",
|
||||
"attendee_no_longer_attending": "一位與會者不再參加您的活動",
|
||||
"attendee_no_longer_attending_subtitle": "{{name}} 已取消,這代表此時段空出了一個座位",
|
||||
"create_event_on": "活動建立日期",
|
||||
"create_routing_form_on": "建立引導表單於",
|
||||
"default_app_link_title": "設定預設應用程式連結",
|
||||
"default_app_link_description": "設定預設應用程式連結,即可讓所有全新建立的活動類型使用您設定的應用程式連結。",
|
||||
"organizer_default_conferencing_app": "主辦者的預設應用程式",
|
||||
@@ -1692,6 +1696,7 @@
|
||||
"booking_questions_title": "預約問題",
|
||||
"booking_questions_description": "自訂預約頁面上的提問問題",
|
||||
"add_a_booking_question": "新增問題",
|
||||
"identifier": "識別項",
|
||||
"duplicate_email": "電子郵件重複",
|
||||
"booking_with_payment_cancelled": "無法再為此活動付費",
|
||||
"booking_with_payment_cancelled_already_paid": "此預約付款的退款已在辦理中。",
|
||||
@@ -1702,6 +1707,7 @@
|
||||
"show_on_booking_page": "在預約頁面上顯示",
|
||||
"get_started_zapier_templates": "開始使用 Zapier 範本",
|
||||
"team_is_unpublished": "已取消發佈 {{team}}",
|
||||
"team_is_unpublished_description": "此 {{entity}} 連結目前無法使用。請聯絡 {{entity}} 擁有者,或請對方發佈。",
|
||||
"team_member": "團隊成員",
|
||||
"a_routing_form": "引導表單",
|
||||
"form_description_placeholder": "表單說明",
|
||||
@@ -1731,13 +1737,16 @@
|
||||
"spot_popular_event_types": "找出熱門活動類型",
|
||||
"spot_popular_event_types_description": "查看哪種活動類型的點閱次數及預約次數最多",
|
||||
"no_responses_yet": "還沒有回應",
|
||||
"no_routes_defined": "未定義任何引導路由",
|
||||
"this_will_be_the_placeholder": "此處會是佔位符",
|
||||
"error_booking_event": "預約活動時發生錯誤,請重新整理頁面然後再試一次",
|
||||
"timeslot_missing_title": "未選擇任何時段",
|
||||
"timeslot_missing_description": "請選擇要預約活動的時段。",
|
||||
"timeslot_missing_cta": "選擇時段",
|
||||
"switch_monthly": "切換至每月檢視",
|
||||
"switch_weekly": "切換至每週檢視",
|
||||
"switch_multiday": "切換至每日檢視",
|
||||
"switch_columnview": "切換至欄檢視",
|
||||
"num_locations": "{{num}} 個地點選項",
|
||||
"select_on_next_step": "於下一步選擇",
|
||||
"this_meeting_has_not_started_yet": "此會議尚未開始",
|
||||
@@ -1776,6 +1785,7 @@
|
||||
"managed_event_dialog_title_one": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?",
|
||||
"managed_event_dialog_title_other": "{{count}} 位成員已有網址 /{{slug}}。是否要替換?",
|
||||
"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": "如果您選擇取代,我們會通知他們;如果不想覆寫既有網址,請返回並移除。",
|
||||
"review_event_type": "查看活動類型",
|
||||
"looking_for_more_analytics": "在找更多分析嗎?",
|
||||
@@ -1791,12 +1801,14 @@
|
||||
"least_booked_members": "最少預約的成員",
|
||||
"events_created": "已建立的活動",
|
||||
"events_completed": "已完成的活動",
|
||||
"events_cancelled": "已取消的活動",
|
||||
"events_rescheduled": "已重新預定的活動",
|
||||
"from_last_period": "從上一個時段",
|
||||
"from_to_date_period": "開始:{{startDate}} 結束:{{endDate}}",
|
||||
"redirect_url_warning": "加入重新導向功能會停用成功頁面。請務必在自訂的成功頁面中註明「預約已確認」。",
|
||||
"event_trends": "活動趨勢",
|
||||
"clear_filters": "清除篩選條件",
|
||||
"clear": "清除",
|
||||
"hold": "保留",
|
||||
"on_booking_option": "預約時收款",
|
||||
"hold_option": "收取缺席費",
|
||||
@@ -1823,6 +1835,18 @@
|
||||
"complete_your_booking": "完成您的預約",
|
||||
"complete_your_booking_subject": "完成您的預約:{{date}} 的 {{title}}",
|
||||
"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}}",
|
||||
"charge_card_dialog_body": "您即將向與會者收取 {{amount, currency}}。確定要繼續嗎?",
|
||||
"charge_attendee": "向與會者收取 {{amount, currency}}",
|
||||
@@ -1831,6 +1855,7 @@
|
||||
"email_invite_team_bulk": "已邀請 {{userCount}} 位使用者",
|
||||
"error_collecting_card": "卡片發生錯誤",
|
||||
"image_size_limit_exceed": "上傳的圖片大小不得超過 5MB 限制",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}:您未獲得授權,無法啟用或停用此工作流程",
|
||||
"inline_embed": "內嵌式嵌入",
|
||||
"load_inline_content": "直接載入您的活動類型及內嵌在其他網站的內容。",
|
||||
"floating_pop_up_button": "浮動式彈出按鈕",
|
||||
@@ -1850,6 +1875,69 @@
|
||||
"connect_google_workspace": "連接 Google Workspace",
|
||||
"google_workspace_admin_tooltip": "您必須是 Workspace 管理員才能使用此功能",
|
||||
"first_event_type_webhook_description": "為此活動類型建立第一個 Webhook",
|
||||
"install_app_on": "安裝應用程式於",
|
||||
"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
|
||||
// @ts-ignore
|
||||
prismaMock.user.findMany.mockResolvedValue(users);
|
||||
prismaMock.booking.findMany.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
getLuckyUser("MAXIMIZE_AVAILABILITY", {
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
"@deploysentinel/playwright": "^0.3.3",
|
||||
"@playwright/test": "^1.31.2",
|
||||
"@snaplet/copycat": "^0.3.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@types/dompurify": "^2.4.0",
|
||||
"c8": "^7.13.0",
|
||||
"dotenv-checker": "^1.1.5",
|
||||
|
||||
@@ -38,27 +38,38 @@ export default function AppCard({
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"border-subtle mb-4",
|
||||
app.isInstalled ? "mt-2" : "mt-6",
|
||||
"rounded-md border",
|
||||
"border-subtle",
|
||||
app?.isInstalled && "mb-4 rounded-md border",
|
||||
!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="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 */}
|
||||
<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
|
||||
className={classNames(
|
||||
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}
|
||||
alt={app?.name}
|
||||
/>
|
||||
</Link>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-emphasis text-base font-semibold leading-4">{app?.name}</span>
|
||||
<p className="text-default max-w-md truncate pt-2 text-sm font-normal ltr:pr-2 rtl:pl-2">
|
||||
<div className="flex flex-col pe-3">
|
||||
<div className="text-emphasis">
|
||||
<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}
|
||||
</p>
|
||||
</div>
|
||||
@@ -105,7 +116,9 @@ export default function AppCard({
|
||||
</div>
|
||||
<div ref={animationRef}>
|
||||
{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>
|
||||
);
|
||||
|
||||
@@ -33,15 +33,10 @@ const AppCategoryNavigation = ({
|
||||
return (
|
||||
<div className={cs("flex flex-col gap-x-6 md:p-0 xl:flex-row", classNames?.root ?? className)}>
|
||||
<div className="hidden xl:block">
|
||||
<VerticalTabs
|
||||
tabs={appCategories}
|
||||
sticky
|
||||
linkProps={{ shallow: true }}
|
||||
itemClassname={classNames?.verticalTabsItem}
|
||||
/>
|
||||
<VerticalTabs tabs={appCategories} sticky linkShallow itemClassname={classNames?.verticalTabsItem} />
|
||||
</div>
|
||||
<div className="block overflow-x-scroll xl:hidden">
|
||||
<HorizontalTabs tabs={appCategories} linkProps={{ shallow: true }} />
|
||||
<HorizontalTabs tabs={appCategories} linkShallow />
|
||||
</div>
|
||||
<main className={classNames?.container ?? containerClassname} ref={animationRef}>
|
||||
{children}
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function OmniInstallAppButton({
|
||||
className="[@media(max-width:260px)]:w-full [@media(max-width:260px)]:justify-center"
|
||||
StartIcon={Plus}
|
||||
{...props}>
|
||||
{t("install")}
|
||||
{t("add")}
|
||||
</Button>
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { google } from "googleapis";
|
||||
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 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 (!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." });
|
||||
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 authUrl = oAuth2Client.generateAuthUrl({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { google } from "googleapis";
|
||||
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 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_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);
|
||||
|
||||
|
||||
@@ -23,6 +23,27 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
||||
}}
|
||||
switchChecked={enabled}
|
||||
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
|
||||
name="Plausible URL"
|
||||
defaultValue="https://plausible.io/js/script.js"
|
||||
|
||||
@@ -46,7 +46,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
||||
}}
|
||||
switchChecked={enabled}
|
||||
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">
|
||||
<TextField
|
||||
name="hello"
|
||||
|
||||
@@ -145,7 +145,7 @@ function NewFormDialog({ appUrl }: { appUrl: string }) {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<DialogFooter showDivider className="mt-12 flex flex-row-reverse gap-x-2">
|
||||
<DialogFooter showDivider className="mt-12">
|
||||
<DialogClose />
|
||||
<Button loading={mutation.isLoading} data-testid="add-form" type="submit">
|
||||
{t("continue")}
|
||||
|
||||
@@ -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.
|
||||
|
||||
## 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.
|
||||
- **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.
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { z } from "zod";
|
||||
|
||||
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
|
||||
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 { MeetLocationType } from "@calcom/app-store/locations";
|
||||
import getApps from "@calcom/app-store/utils";
|
||||
@@ -94,7 +95,22 @@ export default class EventManager {
|
||||
public async create(event: CalendarEvent): Promise<CreateUpdateResult> {
|
||||
const evt = processLocation(event);
|
||||
// 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
|
||||
if (evt.location === MeetLocationType && evt.destinationCalendar?.integration !== "google_calendar") {
|
||||
|
||||
@@ -7,6 +7,7 @@ export type EventNameObjectType = {
|
||||
attendeeName: string;
|
||||
eventType: string;
|
||||
eventName?: string | null;
|
||||
teamName?: string | null;
|
||||
host: string;
|
||||
location?: string;
|
||||
bookingFields?: Prisma.JsonObject;
|
||||
@@ -17,7 +18,7 @@ export function getEventName(eventNameObj: EventNameObjectType, forAttendeeView
|
||||
if (!eventNameObj.eventName)
|
||||
return eventNameObj.t("event_between_users", {
|
||||
eventName: eventNameObj.eventType,
|
||||
host: eventNameObj.host,
|
||||
host: eventNameObj.teamName || eventNameObj.host,
|
||||
attendeeName: eventNameObj.attendeeName,
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
|
||||
@@ -70,16 +70,7 @@ export default class OrganizerScheduledEmail extends BaseEmail {
|
||||
|
||||
protected getNodeMailerPayload(): Record<string, unknown> {
|
||||
const clonedCalEvent = cloneDeep(this.calEvent);
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
|
||||
|
||||
return {
|
||||
icalEvent: {
|
||||
|
||||
@@ -82,10 +82,13 @@
|
||||
</style>
|
||||
</head>
|
||||
<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="?only=prerender-test">Go to Pre-render test page only</a><small></small
|
||||
></span>
|
||||
<button onclick="document.documentElement.style.colorScheme='dark'">Toggle Dark Scheme</button>
|
||||
<button onclick="document.documentElement.style.colorScheme='light'">Toggle Light Scheme</button>
|
||||
<div>
|
||||
<script>
|
||||
if (only === "all" || only === "prerender-test") {
|
||||
|
||||
@@ -6,8 +6,28 @@ const callback = function (e) {
|
||||
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 only = searchParams.get("only");
|
||||
const colorScheme = searchParams.get("color-scheme");
|
||||
|
||||
if (colorScheme) {
|
||||
document.documentElement.style.colorScheme = colorScheme;
|
||||
}
|
||||
const themeInParam = searchParams.get("theme");
|
||||
const validThemes = ["light", "dark", "auto"] as const;
|
||||
const theme = validThemes.includes((themeInParam as (typeof validThemes)[number]) || "")
|
||||
|
||||
@@ -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.
|
||||
cssVarsPerTheme?: Record<Theme, Record<string, string>>;
|
||||
layout?: BookerLayouts;
|
||||
colorScheme?: string | null;
|
||||
};
|
||||
|
||||
type SetStyles = React.Dispatch<React.SetStateAction<EmbedStyles>>;
|
||||
@@ -336,6 +337,10 @@ const methods = {
|
||||
window.CalEmbed.applyCssVars(uiConfig.cssVarsPerTheme);
|
||||
}
|
||||
|
||||
if (uiConfig.colorScheme) {
|
||||
actOnColorScheme(uiConfig.colorScheme);
|
||||
}
|
||||
|
||||
if (embedStore.setUiConfig) {
|
||||
runAllUiSetters(uiConfig);
|
||||
}
|
||||
@@ -461,10 +466,12 @@ if (isBrowser) {
|
||||
|
||||
embedStore.uiConfig = {
|
||||
// TODO: Add theme as well here
|
||||
// theme:
|
||||
colorScheme: url.searchParams.get("ui.color-scheme"),
|
||||
layout: url.searchParams.get("layout") as BookerLayouts,
|
||||
};
|
||||
|
||||
actOnColorScheme(embedStore.uiConfig.colorScheme);
|
||||
|
||||
if (url.searchParams.get("prerender") !== "true" && window?.isEmbed?.()) {
|
||||
log("Initializing embed-iframe");
|
||||
// HACK
|
||||
@@ -523,3 +530,10 @@ function runAllUiSetters(uiConfig: UiConfig) {
|
||||
embedStore.uiConfig = uiConfig;
|
||||
embedStore.setUiConfig.forEach((setUiConfig) => setUiConfig(uiConfig));
|
||||
}
|
||||
|
||||
function actOnColorScheme(colorScheme: string | null | undefined) {
|
||||
if (!colorScheme) {
|
||||
return;
|
||||
}
|
||||
document.documentElement.style.colorScheme = colorScheme;
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
// 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 */} });
|
||||
@@ -139,8 +164,8 @@ export type PrefillAndIframeAttrsConfig = Record<string, string | string[] | Rec
|
||||
// TODO: It should have a dedicated prefill prop
|
||||
// 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.
|
||||
// ui: {layout; theme}
|
||||
// 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.color-scheme"?: string;
|
||||
layout?: `${BookerLayouts}`;
|
||||
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({
|
||||
calLink,
|
||||
queryObject = {},
|
||||
@@ -255,9 +283,14 @@ export class Cal {
|
||||
urlInstance.pathname = `${urlInstance.pathname}/embed`;
|
||||
}
|
||||
urlInstance.searchParams.set("embed", this.namespace);
|
||||
|
||||
if (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) {
|
||||
iframe.style.border = "1px solid green";
|
||||
}
|
||||
@@ -334,6 +367,13 @@ export class Cal {
|
||||
|
||||
this.actionManager.on("__iframeReady", () => {
|
||||
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.iframeDoQueue.forEach((doInIframeArg) => {
|
||||
this.doInIframe(doInIframeArg);
|
||||
@@ -369,7 +409,7 @@ export class Cal {
|
||||
|
||||
class CalApi {
|
||||
cal: Cal;
|
||||
|
||||
static initializedNamespaces = [] as string[];
|
||||
constructor(cal: Cal) {
|
||||
this.cal = cal;
|
||||
}
|
||||
@@ -379,6 +419,8 @@ class CalApi {
|
||||
config = (namespaceOrConfig || {}) as Config;
|
||||
}
|
||||
|
||||
CalApi.initializedNamespaces.push(this.cal.namespace);
|
||||
|
||||
const { calOrigin: calOrigin, origin: origin, ...restConfig } = config;
|
||||
|
||||
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) {
|
||||
throw new Error("iframeAttrs should be an object");
|
||||
}
|
||||
config.embedType = "inline";
|
||||
const iframe = this.cal.createIframe({ calLink, queryObject: Cal.getQueryObject(config) });
|
||||
iframe.style.height = "100%";
|
||||
iframe.style.width = "100%";
|
||||
const element =
|
||||
const containerEl =
|
||||
elementOrSelector instanceof HTMLElement
|
||||
? elementOrSelector
|
||||
: document.querySelector(elementOrSelector);
|
||||
if (!element) {
|
||||
|
||||
if (!containerEl) {
|
||||
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");
|
||||
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.appendChild(iframe);
|
||||
element.appendChild(template.content);
|
||||
containerEl.appendChild(template.content);
|
||||
}
|
||||
|
||||
floatingButton({
|
||||
@@ -523,8 +573,14 @@ class CalApi {
|
||||
if (typeof config.iframeAttrs === "string" || config.iframeAttrs instanceof Array) {
|
||||
throw new Error("iframeAttrs should be an object");
|
||||
}
|
||||
|
||||
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.height = "100%";
|
||||
@@ -537,7 +593,7 @@ class CalApi {
|
||||
this.cal.actionManager.on("__closeIframe", () => {
|
||||
this.cal.modalBox.setAttribute("state", "closed");
|
||||
});
|
||||
document.body.appendChild(template.content);
|
||||
containerEl.appendChild(template.content);
|
||||
}
|
||||
|
||||
on<T extends keyof EventDataMap>({
|
||||
@@ -646,7 +702,9 @@ export interface CalWindow extends Window {
|
||||
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)) {
|
||||
api.instance = new Cal(ns, api.q);
|
||||
}
|
||||
@@ -711,3 +769,32 @@ document.addEventListener("click", (e) => {
|
||||
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 {
|
||||
Button,
|
||||
ConfirmationDialogContent,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogTrigger,
|
||||
showToast,
|
||||
DialogFooter,
|
||||
DialogClose,
|
||||
} from "@calcom/ui";
|
||||
import { Trash, AlertCircle } from "@calcom/ui/components/icon";
|
||||
import { Trash } from "@calcom/ui/components/icon";
|
||||
|
||||
export default function DisconnectIntegration({
|
||||
credentialId,
|
||||
@@ -62,18 +60,15 @@ export default function DisconnectIntegration({
|
||||
{label && label}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent
|
||||
<ConfirmationDialogContent
|
||||
variety="danger"
|
||||
title={t("remove_app")}
|
||||
description={t("are_you_sure_you_want_to_remove_this_app")}
|
||||
type="confirmation"
|
||||
Icon={AlertCircle}>
|
||||
<DialogFooter>
|
||||
<DialogClose onClick={() => setModalOpen(false)} />
|
||||
<DialogClose color="primary" onClick={() => mutation.mutate({ id: credentialId })}>
|
||||
{t("yes_remove_app")}
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
confirmBtnText={t("yes_remove_app")}
|
||||
onConfirm={() => {
|
||||
mutation.mutate({ id: credentialId });
|
||||
}}>
|
||||
<p className="mt-5">{t("are_you_sure_you_want_to_remove_this_app")}</p>
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -115,7 +115,7 @@ const providers: Provider[] = [
|
||||
throw new Error(ErrorCode.IncorrectEmailPassword);
|
||||
}
|
||||
|
||||
if (user.password || !credentials.totpCode) {
|
||||
if (user.password && !credentials.totpCode) {
|
||||
if (!user.password) {
|
||||
throw new Error(ErrorCode.IncorrectEmailPassword);
|
||||
}
|
||||
@@ -560,7 +560,7 @@ export const AUTH_OPTIONS: AuthOptions = {
|
||||
console.error("Error while linking account of already existing user");
|
||||
}
|
||||
}
|
||||
if (existingUser.twoFactorEnabled) {
|
||||
if (existingUser.twoFactorEnabled && existingUser.identityProvider === idP) {
|
||||
return loginWithTotp(existingUser);
|
||||
} else {
|
||||
return true;
|
||||
@@ -600,7 +600,11 @@ export const AUTH_OPTIONS: AuthOptions = {
|
||||
|
||||
if (existingUserWithEmail) {
|
||||
// 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) {
|
||||
return loginWithTotp(existingUserWithEmail);
|
||||
} else {
|
||||
|
||||
@@ -23,7 +23,7 @@ import { useBookerStore, useInitializeBookerStore } from "./store";
|
||||
import type { BookerLayout, BookerProps } from "./types";
|
||||
import { useEvent } from "./utils/event";
|
||||
import { validateLayout } from "./utils/layout";
|
||||
import { getQueryParam } from './utils/query-param';
|
||||
import { getQueryParam } from "./utils/query-param";
|
||||
import { useBrandColors } from "./utils/use-brand-colors";
|
||||
|
||||
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy"));
|
||||
@@ -120,9 +120,9 @@ const BookerComponent = ({
|
||||
layout !== _layout
|
||||
) {
|
||||
const validLayout = bookerLayouts.enabledLayouts.find((userLayout) => userLayout === layout);
|
||||
validLayout && setLayout(validLayout)
|
||||
validLayout && setLayout(validLayout);
|
||||
}
|
||||
}, [bookerLayouts, validateLayout, setLayout,_layout]);
|
||||
}, [bookerLayouts, validateLayout, setLayout, _layout]);
|
||||
|
||||
useEffect(() => {
|
||||
if (event.isLoading) return setBookerState("loading");
|
||||
@@ -302,4 +302,4 @@ export const Booker = (props: BookerProps) => {
|
||||
<BookerComponent {...props} />
|
||||
</LazyMotion>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import type { UseMutationResult } from "@tanstack/react-query";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useSession } from "next-auth/react";
|
||||
import type { TFunction } from "next-i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
@@ -22,6 +23,7 @@ import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/
|
||||
import getBookingResponsesSchema, {
|
||||
getBookingResponsesPartialSchema,
|
||||
} from "@calcom/features/bookings/lib/getBookingResponsesSchema";
|
||||
import { getFullName } from "@calcom/features/form-builder/utils";
|
||||
import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
|
||||
import { MINUTES_TO_BOOK } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
@@ -40,6 +42,7 @@ type BookEventFormProps = {
|
||||
};
|
||||
|
||||
export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
|
||||
const session = useSession();
|
||||
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation({
|
||||
trpc: { context: { skipBatch: true } },
|
||||
});
|
||||
@@ -114,8 +117,12 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
|
||||
});
|
||||
|
||||
const defaultUserValues = {
|
||||
email: rescheduleUid ? bookingData?.attendees[0].email : parsedQuery["email"] || "",
|
||||
name: rescheduleUid ? bookingData?.attendees[0].name : parsedQuery["name"] || "",
|
||||
email: rescheduleUid
|
||||
? bookingData?.attendees[0].email
|
||||
: parsedQuery["email"] || session.data?.user?.email || "",
|
||||
name: rescheduleUid
|
||||
? bookingData?.attendees[0].name
|
||||
: parsedQuery["name"] || session.data?.user?.name || "",
|
||||
};
|
||||
|
||||
if (!isRescheduling) {
|
||||
@@ -193,12 +200,13 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
|
||||
const createBookingMutation = useMutation(createBooking, {
|
||||
onSuccess: async (responseData) => {
|
||||
const { uid, paymentUid } = responseData;
|
||||
const fullName = getFullName(bookingForm.getValues("responses.name"));
|
||||
if (paymentUid) {
|
||||
return await router.push(
|
||||
createPaymentLink({
|
||||
paymentUid,
|
||||
date: timeslot,
|
||||
name: bookingForm.getValues("responses.name"),
|
||||
name: fullName,
|
||||
email: bookingForm.getValues("responses.email"),
|
||||
absolute: false,
|
||||
})
|
||||
|
||||
@@ -2,11 +2,11 @@ import { useFormContext } from "react-hook-form";
|
||||
|
||||
import type { LocationObject } from "@calcom/app-store/locations";
|
||||
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 type { RouterOutputs } from "@calcom/trpc/react";
|
||||
|
||||
import { SystemField } from "../../../lib/getBookingFields";
|
||||
import { SystemField } from "../../../lib/SystemField";
|
||||
|
||||
export const BookingFields = ({
|
||||
fields,
|
||||
@@ -26,6 +26,7 @@ export const BookingFields = ({
|
||||
|
||||
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
|
||||
// The logic here intends to make modifications to booking fields based on the way we want to specifically show Booking Form
|
||||
<div>
|
||||
{fields.map((field, index) => {
|
||||
// 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 =
|
||||
(field.editable === "system" || field.editable === "system-but-optional") && !!rescheduleUid;
|
||||
|
||||
let noLabel = false;
|
||||
let hidden = !!field.hidden;
|
||||
const fieldViews = field.views;
|
||||
|
||||
@@ -88,28 +88,10 @@ export const BookingFields = ({
|
||||
field.options = options.filter(
|
||||
(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 (
|
||||
<FormBuilderField
|
||||
className="mb-4"
|
||||
field={{ ...field, label, placeholder, hidden }}
|
||||
readOnly={readOnly}
|
||||
key={index}
|
||||
/>
|
||||
<FormBuilderField className="mb-4" field={{ ...field, hidden }} readOnly={readOnly} key={index} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -128,7 +128,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
|
||||
if (["week_view", "column_view"].includes(layout) && !get().selectedDate) {
|
||||
set({ selectedDate: dayjs().format("YYYY-MM-DD") });
|
||||
}
|
||||
updateQueryParam("layout", layout)
|
||||
updateQueryParam("layout", layout);
|
||||
return set({ layout });
|
||||
},
|
||||
selectedDate: getQueryParam("date") || null,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { AnimatedPopover } from "@calcom/ui";
|
||||
import { Checkbox } from "@calcom/ui";
|
||||
import { CheckboxField } from "@calcom/ui";
|
||||
|
||||
import { groupBy } from "../groupBy";
|
||||
import { useFilterQuery } from "../lib/useFilterQuery";
|
||||
@@ -73,7 +73,7 @@ export const EventTypeFilter = () => {
|
||||
</div>
|
||||
{groupedEventTypes[teamName].map((eventType) => (
|
||||
<div key={eventType.id} className="flex items-center px-4 py-1.5">
|
||||
<Checkbox
|
||||
<CheckboxField
|
||||
checked={query.eventTypeIds?.includes(eventType.id)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
|
||||
@@ -27,7 +27,7 @@ export const EventDuration = ({ event }: { event: PublicEvent }) => {
|
||||
{event.metadata.multipleDuration.map((duration) => (
|
||||
<Badge
|
||||
variant="gray"
|
||||
className={classNames(selectedDuration === duration && "bg-inverted text-inverted")}
|
||||
className={classNames(selectedDuration === duration && "bg-brand-default text-brand")}
|
||||
size="md"
|
||||
key={duration}
|
||||
onClick={() => setSelectedDuration(duration)}>{`${duration} ${t("minute_timeUnit")}`}</Badge>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { getEventLocationType, getTranslatedLocation } from "@calcom/app-store/locations";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Tooltip } from "@calcom/ui";
|
||||
import { MapPin } from "@calcom/ui/components/icon";
|
||||
import { classNames } from "@calcom/lib";
|
||||
|
||||
import type { PublicEvent } from "../../types";
|
||||
import { EventMetaBlock } from "./Details";
|
||||
@@ -20,7 +20,7 @@ export const EventLocations = ({ event }: { event: PublicEvent }) => {
|
||||
return translatedLocation;
|
||||
};
|
||||
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 (
|
||||
<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">
|
||||
<div className="flex flex-row items-center">
|
||||
<img
|
||||
src={getEventLocationType(location.type)?.iconUrl}
|
||||
className={classNames(
|
||||
"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]" : ""
|
||||
)}
|
||||
alt={`${getEventLocationType(location.type)?.label} icon`}
|
||||
/>
|
||||
src={getEventLocationType(location.type)?.iconUrl}
|
||||
className={classNames(
|
||||
"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]"
|
||||
: ""
|
||||
)}
|
||||
alt={`${getEventLocationType(location.type)?.label} icon`}
|
||||
/>
|
||||
<span>{getLocationToDisplay(location)}</span>
|
||||
</div>
|
||||
</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 { z } from "zod";
|
||||
import type { z } from "zod";
|
||||
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { EventTypeCustomInputType } from "@calcom/prisma/enums";
|
||||
import {
|
||||
BookingFieldType,
|
||||
BookingFieldTypeEnum,
|
||||
customInputSchema,
|
||||
eventTypeBookingFields,
|
||||
EventTypeMetaDataSchema,
|
||||
} 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";
|
||||
|
||||
/**
|
||||
@@ -42,18 +48,6 @@ export const getSmsReminderNumberSource = ({
|
||||
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
|
||||
*/
|
||||
@@ -125,12 +119,12 @@ export const ensureBookingInputsHaveSystemFields = ({
|
||||
// If bookingFields is set already, the migration is done.
|
||||
const handleMigration = !bookingFields.length;
|
||||
const CustomInputTypeToFieldType = {
|
||||
[EventTypeCustomInputType.TEXT]: BookingFieldType.text,
|
||||
[EventTypeCustomInputType.TEXTLONG]: BookingFieldType.textarea,
|
||||
[EventTypeCustomInputType.NUMBER]: BookingFieldType.number,
|
||||
[EventTypeCustomInputType.BOOL]: BookingFieldType.boolean,
|
||||
[EventTypeCustomInputType.RADIO]: BookingFieldType.radio,
|
||||
[EventTypeCustomInputType.PHONE]: BookingFieldType.phone,
|
||||
[EventTypeCustomInputType.TEXT]: BookingFieldTypeEnum.text,
|
||||
[EventTypeCustomInputType.TEXTLONG]: BookingFieldTypeEnum.textarea,
|
||||
[EventTypeCustomInputType.NUMBER]: BookingFieldTypeEnum.number,
|
||||
[EventTypeCustomInputType.BOOL]: BookingFieldTypeEnum.boolean,
|
||||
[EventTypeCustomInputType.RADIO]: BookingFieldTypeEnum.radio,
|
||||
[EventTypeCustomInputType.PHONE]: BookingFieldTypeEnum.phone,
|
||||
};
|
||||
|
||||
const smsNumberSources = [] as NonNullable<(typeof bookingFields)[number]["sources"]>;
|
||||
@@ -151,10 +145,12 @@ export const ensureBookingInputsHaveSystemFields = ({
|
||||
// These fields should be added before other user fields
|
||||
const systemBeforeFields: typeof bookingFields = [
|
||||
{
|
||||
defaultLabel: "your_name",
|
||||
type: "name",
|
||||
// This is the `name` of the main field
|
||||
name: "name",
|
||||
editable: "system",
|
||||
// This Label is used in Email only as of now.
|
||||
defaultLabel: "your_name",
|
||||
required: true,
|
||||
sources: [
|
||||
{
|
||||
@@ -332,7 +328,6 @@ export const ensureBookingInputsHaveSystemFields = ({
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bookingFields = bookingFields.concat(missingSystemAfterFields);
|
||||
|
||||
return eventTypeBookingFields.brand<"HAS_SYSTEM_FIELDS">().parse(bookingFields);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { isValidPhoneNumber } from "libphonenumber-js";
|
||||
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 { 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
|
||||
type View = ALL_VIEWS | (string & {});
|
||||
|
||||
export const bookingResponse = z.union([
|
||||
z.string(),
|
||||
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);
|
||||
export const bookingResponse = dbReadResponseSchema;
|
||||
export const bookingResponsesDbSchema = z.record(dbReadResponseSchema);
|
||||
|
||||
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
|
||||
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") {
|
||||
// Turn a boolean in string to a real boolean
|
||||
newResponses[field.name] = value === "true" || value === true;
|
||||
@@ -149,6 +149,19 @@ function preprocess<T extends z.ZodType>({
|
||||
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") {
|
||||
const emailsParsed = emailSchema.array().safeParse(value);
|
||||
if (!emailsParsed.success) {
|
||||
@@ -217,9 +230,9 @@ function preprocess<T extends z.ZodType>({
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
["address", "text", "select", "name", "number", "radio", "textarea"].includes(bookingField.type)
|
||||
) {
|
||||
// Use fieldTypeConfig.propsType to validate for propsType=="text" or propsType=="select" as in those cases, the response would be a string.
|
||||
// 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;
|
||||
if (!schema.safeParse(value).success) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: m("Invalid string") });
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 { getBookingWithResponses } from "@calcom/lib/getBooking";
|
||||
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
@@ -43,6 +43,7 @@ export const getCalEventResponses = ({
|
||||
parsedBookingFields.forEach((field) => {
|
||||
const label = field.label || field.defaultLabel;
|
||||
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 + '"');
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { HttpError } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { handleRefundError } from "@calcom/lib/payment/handleRefundError";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
|
||||
import { BookingStatus, MembershipRole, WorkflowMethods, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
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
|
||||
email: true,
|
||||
timeZone: true,
|
||||
timeFormat: true,
|
||||
name: true,
|
||||
destinationCalendar: true,
|
||||
},
|
||||
@@ -154,6 +156,7 @@ async function handler(req: CustomRequest) {
|
||||
name: true,
|
||||
email: true,
|
||||
timeZone: true,
|
||||
timeFormat: true,
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
@@ -207,6 +210,7 @@ async function handler(req: CustomRequest) {
|
||||
email: organizer.email,
|
||||
name: organizer.name ?? "Nameless",
|
||||
timeZone: organizer.timeZone,
|
||||
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
|
||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||
},
|
||||
attendees: attendeesList,
|
||||
@@ -540,6 +544,7 @@ async function handler(req: CustomRequest) {
|
||||
email: bookingToDelete.user?.email ?? "dev@calendso.com",
|
||||
name: bookingToDelete.user?.name ?? "no user",
|
||||
timeZone: bookingToDelete.user?.timeZone ?? "",
|
||||
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
|
||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||
},
|
||||
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 { deleteScheduledSMSReminder } from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
|
||||
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 getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
|
||||
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 { slugify } from "@calcom/lib/slugify";
|
||||
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 type { BookingReference } from "@calcom/prisma/client";
|
||||
import { BookingStatus, SchedulingType, WebhookTriggerEvents, WorkflowMethods } from "@calcom/prisma/enums";
|
||||
@@ -598,6 +599,7 @@ function getBookingData({
|
||||
throw new Error("`responses` must not be nullish");
|
||||
}
|
||||
const responses = reqBody.responses;
|
||||
|
||||
const { userFieldsResponses: calEventUserFieldsResponses, responses: calEventResponses } =
|
||||
getCalEventResponses({
|
||||
bookingFields: eventType.bookingFields,
|
||||
@@ -722,6 +724,8 @@ async function handler(
|
||||
eventType,
|
||||
});
|
||||
|
||||
const fullName = getFullName(bookerName);
|
||||
|
||||
const tAttendees = await getTranslation(language ?? "en", "common");
|
||||
const tGuests = await getTranslation("en", "common");
|
||||
log.debug(`Booking eventType ${eventTypeId} started`);
|
||||
@@ -937,7 +941,7 @@ async function handler(
|
||||
const invitee = [
|
||||
{
|
||||
email: bookerEmail,
|
||||
name: bookerName,
|
||||
name: fullName,
|
||||
timeZone: reqBody.timeZone,
|
||||
language: { translate: tAttendees, locale: language ?? "en" },
|
||||
},
|
||||
@@ -990,9 +994,11 @@ async function handler(
|
||||
|
||||
const eventNameObject = {
|
||||
//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,
|
||||
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.
|
||||
host: organizerUser.name || "Nameless",
|
||||
location: bookingLocation,
|
||||
@@ -1027,7 +1033,7 @@ async function handler(
|
||||
username: organizerUser.username || undefined,
|
||||
timeZone: organizerUser.timeZone,
|
||||
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,
|
||||
userFieldsResponses: calEventUserFieldsResponses,
|
||||
|
||||
@@ -49,7 +49,7 @@ export function DateValues({ days, containerNavRef }: Props) {
|
||||
<span
|
||||
className={classNames(
|
||||
"items-center justify-center p-1",
|
||||
isToday && "bg-inverted text-inverted rounded-full"
|
||||
isToday && "bg-brand-default text-brand rounded-full"
|
||||
)}>
|
||||
{day.format("DD")}
|
||||
</span>
|
||||
|
||||
@@ -101,7 +101,7 @@ function Cell({ isDisabled, topOffsetMinutes, timeSlot }: CellProps) {
|
||||
{!isDisabled && hoverEventDuration !== 0 && (
|
||||
<div
|
||||
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-center"
|
||||
)}
|
||||
|
||||
@@ -223,8 +223,11 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
|
||||
defaultValue={value}
|
||||
onChange={(e) => {
|
||||
const domain = extractDomainFromEmail(e?.target.value);
|
||||
newOrganizationFormMethods.setValue("adminEmail", e?.target.value);
|
||||
newOrganizationFormMethods.setValue("adminUsername", e?.target.value.split("@")[0]);
|
||||
newOrganizationFormMethods.setValue("adminEmail", e?.target.value.trim());
|
||||
newOrganizationFormMethods.setValue(
|
||||
"adminUsername",
|
||||
e?.target.value.split("@")[0].trim()
|
||||
);
|
||||
if (newOrganizationFormMethods.getValues("slug") === "") {
|
||||
newOrganizationFormMethods.setValue("slug", domain);
|
||||
}
|
||||
@@ -256,7 +259,7 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
|
||||
label={t("organization_name")}
|
||||
defaultValue={value}
|
||||
onChange={(e) => {
|
||||
newOrganizationFormMethods.setValue("name", e?.target.value);
|
||||
newOrganizationFormMethods.setValue("name", e?.target.value.trim());
|
||||
if (newOrganizationFormMethods.formState.touchedFields["slug"] === undefined) {
|
||||
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 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 { UserListTable } from "@calcom/features/users/components/UserTable/UserListTable";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
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>
|
||||
);
|
||||
}
|
||||
import { Meta } from "@calcom/ui";
|
||||
|
||||
const MembersView = () => {
|
||||
const { t, i18n } = 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);
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
<LicenseRequired>
|
||||
<Meta
|
||||
title={t("organization_members")}
|
||||
description={t("organization_description")}
|
||||
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 && (
|
||||
<Meta title={t("organization_members")} description={t("organization_description")} />
|
||||
<div>
|
||||
{/* {team && (
|
||||
<>
|
||||
{isInviteOpen && (
|
||||
<TeamInviteList
|
||||
@@ -144,30 +28,9 @@ const MembersView = () => {
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<MembersList team={team} />
|
||||
</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,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
)} */}
|
||||
<UserListTable />
|
||||
</div>
|
||||
</LicenseRequired>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import { prisma, bookingMinimalSelect } from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
@@ -59,6 +60,7 @@ async function getBooking(bookingId: number) {
|
||||
id: true,
|
||||
username: true,
|
||||
timeZone: true,
|
||||
timeFormat: true,
|
||||
email: true,
|
||||
name: true,
|
||||
locale: true,
|
||||
@@ -108,6 +110,7 @@ async function getBooking(bookingId: number) {
|
||||
email: user.email,
|
||||
name: user.name!,
|
||||
timeZone: user.timeZone,
|
||||
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
|
||||
language: { translate: t, locale: user.locale ?? "en" },
|
||||
id: user.id,
|
||||
},
|
||||
@@ -163,6 +166,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
||||
username: true,
|
||||
credentials: true,
|
||||
timeZone: true,
|
||||
timeFormat: true,
|
||||
email: true,
|
||||
name: true,
|
||||
locale: true,
|
||||
@@ -216,6 +220,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
||||
email: user.email,
|
||||
name: user.name!,
|
||||
timeZone: user.timeZone,
|
||||
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
|
||||
language: { translate: t, locale: user.locale ?? "en" },
|
||||
},
|
||||
attendees: attendeesList,
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { StripePaymentData, StripeSetupIntentData } from "@calcom/app-store
|
||||
import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
|
||||
import { CAL_URL } from "@calcom/lib/constants";
|
||||
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";
|
||||
|
||||
@@ -101,7 +101,7 @@ const PaymentForm = (props: Props) => {
|
||||
</div>
|
||||
{paymentOption === "HOLD" && (
|
||||
<div className="bg-info mb-5 mt-2 rounded-md p-3">
|
||||
<Checkbox
|
||||
<CheckboxField
|
||||
description={t("acknowledge_booking_no_show_fee", {
|
||||
amount: props.payment.amount / 100,
|
||||
formatParams: { amount: { currency: props.payment.currency } },
|
||||
@@ -116,8 +116,7 @@ const PaymentForm = (props: Props) => {
|
||||
color="minimal"
|
||||
disabled={!holdAcknowledged || ["processing", "error"].includes(state.status)}
|
||||
id="cancel"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
onClick={() => router.back()}>
|
||||
<span id="button-text">{t("cancel")}</span>
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -102,7 +102,7 @@ export default function MemberChangeRoleModal(props: {
|
||||
{errorMessage}
|
||||
</p>
|
||||
)}
|
||||
<DialogFooter showDivider className="mt-12 sm:flex sm:flex-row-reverse">
|
||||
<DialogFooter className="mt-12">
|
||||
<Button type="button" color="secondary" onClick={props.onExit}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { RouterOutputs } from "@calcom/trpc";
|
||||
import { trpc } from "@calcom/trpc";
|
||||
import {
|
||||
Button,
|
||||
Checkbox as CheckboxField,
|
||||
CheckboxField,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
||||
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
@@ -196,6 +197,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
reminder.workflowStep.emailSubject || "",
|
||||
variables,
|
||||
emailLocale,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||
!!reminder.booking.user?.hideBranding
|
||||
).text;
|
||||
emailContent.emailSubject = emailSubject;
|
||||
@@ -203,16 +205,22 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
reminder.workflowStep.reminderBody || "",
|
||||
variables,
|
||||
emailLocale,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||
!!reminder.booking.user?.hideBranding
|
||||
).html;
|
||||
|
||||
emailBodyEmpty =
|
||||
customTemplate(reminder.workflowStep.reminderBody || "", variables, emailLocale).text.length ===
|
||||
0;
|
||||
customTemplate(
|
||||
reminder.workflowStep.reminderBody || "",
|
||||
variables,
|
||||
emailLocale,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
|
||||
).text.length === 0;
|
||||
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
||||
emailContent = emailReminderTemplate(
|
||||
false,
|
||||
reminder.workflowStep.action,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||
reminder.booking.startTime.toISOString() || "",
|
||||
reminder.booking.endTime.toISOString() || "",
|
||||
reminder.booking.eventType?.title || "",
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
||||
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
@@ -116,13 +117,15 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const customMessage = customTemplate(
|
||||
reminder.workflowStep.reminderBody || "",
|
||||
variables,
|
||||
locale || "en"
|
||||
locale || "en",
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
|
||||
);
|
||||
message = customMessage.text;
|
||||
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
||||
message = smsReminderTemplate(
|
||||
false,
|
||||
reminder.workflowStep.action,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||
reminder.booking?.startTime.toISOString() || "",
|
||||
reminder.booking?.eventType?.title || "",
|
||||
timeZone || "",
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { getWhatsappTemplateFunction } from "../lib/actionHelperFunctions";
|
||||
@@ -81,6 +82,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const message = templateFunction(
|
||||
false,
|
||||
reminder.workflowStep.action,
|
||||
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||
reminder.booking?.startTime.toISOString() || "",
|
||||
reminder.booking?.eventType?.title || "",
|
||||
timeZone || "",
|
||||
|
||||
@@ -11,7 +11,7 @@ import { WorkflowActions } from "@calcom/prisma/enums";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
CheckboxField,
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
@@ -93,7 +93,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
setIsPhoneNumberNeeded(true);
|
||||
setIsSenderIdNeeded(true);
|
||||
setIsEmailAddressNeeded(false);
|
||||
form.resetField("senderId", { defaultValue: SENDER_ID })
|
||||
form.resetField("senderId", { defaultValue: SENDER_ID });
|
||||
} else if (newValue.value === WorkflowActions.EMAIL_ADDRESS) {
|
||||
setIsEmailAddressNeeded(true);
|
||||
setIsSenderIdNeeded(false);
|
||||
@@ -102,7 +102,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
setIsSenderIdNeeded(true);
|
||||
setIsEmailAddressNeeded(false);
|
||||
setIsPhoneNumberNeeded(false);
|
||||
form.resetField("senderId", { defaultValue: SENDER_ID })
|
||||
form.resetField("senderId", { defaultValue: SENDER_ID });
|
||||
} else if (newValue.value === WorkflowActions.WHATSAPP_NUMBER) {
|
||||
setIsSenderIdNeeded(false);
|
||||
setIsPhoneNumberNeeded(true);
|
||||
@@ -123,17 +123,16 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
|
||||
const canRequirePhoneNumber = (workflowStep: string) => {
|
||||
return (
|
||||
WorkflowActions.SMS_ATTENDEE === workflowStep ||
|
||||
WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
|
||||
)
|
||||
}
|
||||
WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
|
||||
);
|
||||
};
|
||||
|
||||
const showSender = (action: string) => {
|
||||
return !isSenderIdNeeded && !(
|
||||
WorkflowActions.WHATSAPP_NUMBER === action ||
|
||||
WorkflowActions.WHATSAPP_ATTENDEE === action
|
||||
)
|
||||
}
|
||||
return (
|
||||
!isSenderIdNeeded &&
|
||||
!(WorkflowActions.WHATSAPP_NUMBER === action || WorkflowActions.WHATSAPP_ATTENDEE === action)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}>
|
||||
@@ -186,7 +185,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
{isPhoneNumberNeeded && (
|
||||
<div className="mt-5 space-y-1">
|
||||
<Label htmlFor="sendTo">{t("phone_number")}</Label>
|
||||
<div className="mt-1 mb-5">
|
||||
<div className="mb-5 mt-1">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="sendTo"
|
||||
@@ -228,7 +227,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{showSender(form.getValues('action')) && (
|
||||
{showSender(form.getValues("action")) && (
|
||||
<div className="mt-5">
|
||||
<Label>{t("sender_name")}</Label>
|
||||
<Input type="text" placeholder={SENDER_NAME} {...form.register(`senderName`)} />
|
||||
@@ -240,7 +239,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||
name="numberRequired"
|
||||
control={form.control}
|
||||
render={() => (
|
||||
<Checkbox
|
||||
<CheckboxField
|
||||
defaultChecked={form.getValues("numberRequired") || false}
|
||||
description={t("make_phone_number_required")}
|
||||
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 type { WorkflowActions } from "@calcom/prisma/enums";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
||||
import { Button, Label, MultiSelectCheckboxes, TextField } from "@calcom/ui";
|
||||
import { ArrowDown, Trash2 } from "@calcom/ui/components/icon";
|
||||
@@ -19,12 +20,15 @@ import { AddActionDialog } from "./AddActionDialog";
|
||||
import { DeleteDialog } from "./DeleteDialog";
|
||||
import WorkflowStepContainer from "./WorkflowStepContainer";
|
||||
|
||||
type User = RouterOutputs["viewer"]["me"];
|
||||
|
||||
interface Props {
|
||||
form: UseFormReturn<FormValues>;
|
||||
workflowId: number;
|
||||
selectedEventTypes: Option[];
|
||||
setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>;
|
||||
teamId?: number;
|
||||
user: User;
|
||||
isMixedEventType: 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">
|
||||
{form.getValues("trigger") && (
|
||||
<div>
|
||||
<WorkflowStepContainer form={form} teamId={teamId} readOnly={props.readOnly} />
|
||||
<WorkflowStepContainer form={form} user={props.user} teamId={teamId} readOnly={props.readOnly} />
|
||||
</div>
|
||||
)}
|
||||
{form.getValues("steps") && (
|
||||
@@ -168,6 +172,7 @@ export default function WorkflowDetailsPage(props: Props) {
|
||||
<WorkflowStepContainer
|
||||
key={step.id}
|
||||
form={form}
|
||||
user={props.user}
|
||||
step={step}
|
||||
reload={reload}
|
||||
setReload={setReload}
|
||||
|
||||
@@ -9,13 +9,15 @@ import { classNames } from "@calcom/lib";
|
||||
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import { WorkflowTemplates, TimeUnit, WorkflowActions } from "@calcom/prisma/enums";
|
||||
import { WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
CheckboxField,
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
@@ -39,8 +41,14 @@ import {
|
||||
} from "@calcom/ui";
|
||||
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 { isAttendeeAction, isSMSAction, isSMSOrWhatsappAction, isWhatsappAction, getWhatsappTemplateForAction } from "../lib/actionHelperFunctions";
|
||||
import { getWorkflowTemplateOptions, getWorkflowTriggerOptions } from "../lib/getOptions";
|
||||
import emailReminderTemplate from "../lib/reminders/templates/emailReminderTemplate";
|
||||
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 { TimeTimeUnitInput } from "./TimeTimeUnitInput";
|
||||
|
||||
type User = RouterOutputs["viewer"]["me"];
|
||||
|
||||
type WorkflowStepProps = {
|
||||
step?: WorkflowStep;
|
||||
form: UseFormReturn<FormValues>;
|
||||
user: User;
|
||||
reload?: boolean;
|
||||
setReload?: Dispatch<SetStateAction<boolean>>;
|
||||
teamId?: number;
|
||||
@@ -66,19 +77,24 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
{ teamId },
|
||||
{ enabled: !!teamId }
|
||||
);
|
||||
|
||||
const timeFormat = getTimeFormatStringFromUserTimeFormat(props.user.timeFormat);
|
||||
|
||||
const verifiedNumbers = _verifiedNumbers?.map((number) => number.phoneNumber) || [];
|
||||
const [isAdditionalInputsDialogOpen, setIsAdditionalInputsDialogOpen] = useState(false);
|
||||
|
||||
const [verificationCode, setVerificationCode] = useState("");
|
||||
|
||||
const action = step?.action
|
||||
const requirePhoneNumber = WorkflowActions.SMS_NUMBER === action || WorkflowActions.WHATSAPP_NUMBER === action;
|
||||
const action = step?.action;
|
||||
const requirePhoneNumber =
|
||||
WorkflowActions.SMS_NUMBER === action || WorkflowActions.WHATSAPP_NUMBER === action;
|
||||
const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(requirePhoneNumber);
|
||||
|
||||
const [updateTemplate, setUpdateTemplate] = useState(false);
|
||||
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);
|
||||
|
||||
@@ -110,33 +126,31 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
if (!form.getValues(`steps.${step.stepNumber - 1}.reminderBody`)) {
|
||||
const action = form.getValues(`steps.${step.stepNumber - 1}.action`);
|
||||
if (isSMSAction(action)) {
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, smsReminderTemplate(
|
||||
true,
|
||||
action
|
||||
));
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
smsReminderTemplate(true, action, timeFormat)
|
||||
);
|
||||
} else if (isWhatsappAction(action)) {
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, whatsappReminderTemplate(
|
||||
true,
|
||||
action
|
||||
))
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
whatsappReminderTemplate(true, action, timeFormat)
|
||||
);
|
||||
} else {
|
||||
const reminderBodyTemplate = emailReminderTemplate(
|
||||
true,
|
||||
action
|
||||
).emailBody;
|
||||
const reminderBodyTemplate = emailReminderTemplate(true, action, timeFormat).emailBody;
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, reminderBodyTemplate);
|
||||
}
|
||||
}
|
||||
if (!form.getValues(`steps.${step.stepNumber - 1}.emailSubject`)) {
|
||||
const subjectTemplate = emailReminderTemplate(
|
||||
true,
|
||||
form.getValues(`steps.${step.stepNumber - 1}.action`)
|
||||
form.getValues(`steps.${step.stepNumber - 1}.action`),
|
||||
timeFormat
|
||||
).emailSubject;
|
||||
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, subjectTemplate);
|
||||
}
|
||||
} else if (step && isWhatsappAction(step.action)) {
|
||||
const templateBody = getWhatsappTemplateForAction(step.action, step.template)
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody)
|
||||
const templateBody = getWhatsappTemplateForAction(step.action, step.template, timeFormat);
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody);
|
||||
}
|
||||
|
||||
const { ref: emailSubjectFormRef, ...restEmailSubjectForm } = step
|
||||
@@ -151,7 +165,11 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
|
||||
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());
|
||||
|
||||
@@ -236,17 +254,17 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
return (
|
||||
<>
|
||||
<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="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
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-base font-bold text-emphasis">{t("trigger")}</div>
|
||||
<div className="text-sm text-default">{t("when_something_happens")}</div>
|
||||
<div className="text-emphasis text-base font-bold">{t("trigger")}</div>
|
||||
<div className="text-default text-sm">{t("when_something_happens")}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-subtle my-7" />
|
||||
<div className="border-subtle my-7 border-t" />
|
||||
<Label>{t("when")}</Label>
|
||||
<Controller
|
||||
name="trigger"
|
||||
@@ -291,7 +309,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
<Label>{showTimeSectionAfter ? t("how_long_after") : t("how_long_before")}</Label>
|
||||
<TimeTimeUnitInput form={form} disabled={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" />
|
||||
<p className="text-sm">{t("testing_workflow_info_message")}</p>
|
||||
</div>
|
||||
@@ -318,18 +336,17 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
|
||||
const canRequirePhoneNumber = (workflowStep: string) => {
|
||||
return (
|
||||
WorkflowActions.SMS_ATTENDEE === workflowStep ||
|
||||
WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
|
||||
)
|
||||
}
|
||||
WorkflowActions.SMS_ATTENDEE === workflowStep || WorkflowActions.WHATSAPP_ATTENDEE === workflowStep
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex justify-center my-3">
|
||||
<div className="my-3 flex justify-center">
|
||||
<ArrowDown className="text-subtle stroke-[1.5px] text-3xl" />
|
||||
</div>
|
||||
<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="flex">
|
||||
<div className="w-full">
|
||||
@@ -338,8 +355,8 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
{step.stepNumber + 1}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-base font-bold text-emphasis">{t("action")}</div>
|
||||
<div className="text-sm text-default">{t("action_is_performed")}</div>
|
||||
<div className="text-emphasis text-base font-bold">{t("action")}</div>
|
||||
<div className="text-default text-sm">{t("action_is_performed")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -379,7 +396,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="border-t border-subtle my-7" />
|
||||
<div className="border-subtle my-7 border-t" />
|
||||
<div>
|
||||
<Label>{t("do_this")}</Label>
|
||||
<Controller
|
||||
@@ -395,16 +412,18 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
if (val) {
|
||||
const oldValue = form.getValues(`steps.${step.stepNumber - 1}.action`);
|
||||
|
||||
const setNumberRequiredConfigs = (phoneNumberIsNeeded: boolean, senderNeeded = true) => {
|
||||
const setNumberRequiredConfigs = (
|
||||
phoneNumberIsNeeded: boolean,
|
||||
senderNeeded = true
|
||||
) => {
|
||||
setIsSenderIsNeeded(senderNeeded);
|
||||
setIsEmailAddressNeeded(false);
|
||||
setIsPhoneNumberNeeded(phoneNumberIsNeeded);
|
||||
setNumberVerified(getNumberVerificationStatus());
|
||||
}
|
||||
};
|
||||
|
||||
if (isSMSAction(val.value)) {
|
||||
|
||||
setNumberRequiredConfigs(val.value === WorkflowActions.SMS_NUMBER)
|
||||
setNumberRequiredConfigs(val.value === WorkflowActions.SMS_NUMBER);
|
||||
// email action changes to sms action
|
||||
if (!isSMSAction(oldValue)) {
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
|
||||
@@ -459,15 +478,19 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
if (isSMSAction(val.value)) {
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
smsReminderTemplate(true, val.value)
|
||||
smsReminderTemplate(true, val.value, timeFormat)
|
||||
);
|
||||
} else if (isWhatsappAction(val.value)) {
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
whatsappReminderTemplate(true, val.value)
|
||||
whatsappReminderTemplate(true, val.value, timeFormat)
|
||||
);
|
||||
} else {
|
||||
const emailReminderBody = emailReminderTemplate(true, val.value);
|
||||
const emailReminderBody = emailReminderTemplate(
|
||||
true,
|
||||
val.value,
|
||||
timeFormat
|
||||
);
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
emailReminderBody.emailBody
|
||||
@@ -501,7 +524,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
/>
|
||||
</div>
|
||||
{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>
|
||||
<div className="block sm:flex">
|
||||
<Controller
|
||||
@@ -553,7 +576,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
) : (
|
||||
!props.readOnly && (
|
||||
<>
|
||||
<div className="flex mt-3">
|
||||
<div className="mt-3 flex">
|
||||
<TextField
|
||||
className="rounded-r-none border-r-transparent"
|
||||
placeholder="Verification code"
|
||||
@@ -589,50 +612,52 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{!isWhatsappAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (<div className="p-4 pt-0 mt-2 rounded-md bg-muted">
|
||||
{isSenderIsNeeded ? (
|
||||
<>
|
||||
<div className="pt-4">
|
||||
<div className="flex">
|
||||
<Label>{t("sender_id")}</Label>
|
||||
<Tooltip content={t("sender_id_info")}>
|
||||
<Info className="ml-2 mr-1 mt-0.5 h-4 w-4 text-gray-500" />
|
||||
</Tooltip>
|
||||
{!isWhatsappAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (
|
||||
<div className="bg-muted mt-2 rounded-md p-4 pt-0">
|
||||
{isSenderIsNeeded ? (
|
||||
<>
|
||||
<div className="pt-4">
|
||||
<div className="flex">
|
||||
<Label>{t("sender_id")}</Label>
|
||||
<Tooltip content={t("sender_id_info")}>
|
||||
<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>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder={SENDER_ID}
|
||||
disabled={props.readOnly}
|
||||
maxLength={11}
|
||||
{...form.register(`steps.${step.stepNumber - 1}.sender`)}
|
||||
/>
|
||||
</div>
|
||||
{form.formState.errors.steps &&
|
||||
form.formState?.errors?.steps[step.stepNumber - 1]?.sender && (
|
||||
<p className="mt-1 text-xs text-red-500">{t("sender_id_error_message")}</p>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="pt-4">
|
||||
<Label>{t("sender_name")}</Label>
|
||||
<Input
|
||||
type="text"
|
||||
disabled={props.readOnly}
|
||||
placeholder={SENDER_NAME}
|
||||
{...form.register(`steps.${step.stepNumber - 1}.senderName`)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>)}
|
||||
{form.formState.errors.steps &&
|
||||
form.formState?.errors?.steps[step.stepNumber - 1]?.sender && (
|
||||
<p className="mt-1 text-xs text-red-500">{t("sender_id_error_message")}</p>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="pt-4">
|
||||
<Label>{t("sender_name")}</Label>
|
||||
<Input
|
||||
type="text"
|
||||
disabled={props.readOnly}
|
||||
placeholder={SENDER_NAME}
|
||||
{...form.register(`steps.${step.stepNumber - 1}.senderName`)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{canRequirePhoneNumber(form.getValues(`steps.${step.stepNumber - 1}.action`)) && (
|
||||
<div className="mt-2">
|
||||
<Controller
|
||||
name={`steps.${step.stepNumber - 1}.numberRequired`}
|
||||
control={form.control}
|
||||
render={() => (
|
||||
<Checkbox
|
||||
<CheckboxField
|
||||
disabled={props.readOnly}
|
||||
defaultChecked={
|
||||
form.getValues(`steps.${step.stepNumber - 1}.numberRequired`) || false
|
||||
@@ -647,7 +672,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
</div>
|
||||
)}
|
||||
{isEmailAddressNeeded && (
|
||||
<div className="p-4 mt-5 rounded-md bg-muted">
|
||||
<div className="bg-muted mt-5 rounded-md p-4">
|
||||
<EmailField
|
||||
required
|
||||
disabled={props.readOnly}
|
||||
@@ -669,40 +694,40 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
isDisabled={props.readOnly}
|
||||
onChange={(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 (isWhatsappAction(action)) {
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
whatsappReminderTemplate(
|
||||
true,
|
||||
action
|
||||
)
|
||||
whatsappReminderTemplate(true, action, timeFormat)
|
||||
);
|
||||
} else if (isSMSAction(action)) {
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
smsReminderTemplate(true,action)
|
||||
smsReminderTemplate(true, action, timeFormat)
|
||||
);
|
||||
} else {
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||
emailReminderTemplate(true, action).emailBody
|
||||
emailReminderTemplate(true, action, timeFormat).emailBody
|
||||
);
|
||||
form.setValue(
|
||||
`steps.${step.stepNumber - 1}.emailSubject`,
|
||||
emailReminderTemplate(true, action).emailSubject
|
||||
emailReminderTemplate(true, action, timeFormat).emailSubject
|
||||
);
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
|
||||
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, "");
|
||||
}
|
||||
}
|
||||
field.onChange(val.value)
|
||||
field.onChange(val.value);
|
||||
form.setValue(`steps.${step.stepNumber - 1}.template`, val.value);
|
||||
setUpdateTemplate(!updateTemplate);
|
||||
}
|
||||
@@ -715,7 +740,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
}}
|
||||
/>
|
||||
</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 && (
|
||||
<div className="mb-6">
|
||||
<div className="flex items-center">
|
||||
@@ -755,7 +780,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
step.action !== WorkflowActions.SMS_NUMBER ? (
|
||||
<>
|
||||
<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")}
|
||||
</Label>
|
||||
</div>
|
||||
@@ -795,7 +820,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
reminderBodyFormRef?.(e);
|
||||
refReminderBody.current = e;
|
||||
}}
|
||||
className="h-24 my-0"
|
||||
className="my-0 h-24"
|
||||
disabled={props.readOnly}
|
||||
required
|
||||
{...restReminderBodyForm}
|
||||
@@ -811,7 +836,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
{!props.readOnly && (
|
||||
<div className="mt-3 ">
|
||||
<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" />
|
||||
<p className="text-left">{t("using_booking_questions_as_variables")}</p>
|
||||
</div>
|
||||
@@ -920,26 +945,26 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog> */}
|
||||
<Dialog open={isAdditionalInputsDialogOpen} onOpenChange={setIsAdditionalInputsDialogOpen}>
|
||||
<DialogContent type="creation" className="sm:max-w-[610px]">
|
||||
<div className="-m-3 h-[430px] overflow-x-hidden overflow-y-scroll sm:m-0">
|
||||
<DialogContent enableOverflow type="creation" className="sm:max-w-[610px]">
|
||||
<div>
|
||||
<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">
|
||||
<p className="font-medium test-sm">{t("format")}</p>
|
||||
<ul className="mt-2 ml-5 list-disc text-emphasis">
|
||||
<div className="bg-muted-3 mb-6 rounded-md sm:p-4">
|
||||
<p className="test-sm font-medium">{t("format")}</p>
|
||||
<ul className="text-emphasis ml-5 mt-2 list-disc">
|
||||
<li>{t("uppercase_for_letters")}</li>
|
||||
<li>{t("replace_whitespaces_underscores")}</li>
|
||||
<li>{t("ignore_special_characters_booking_questions")}</li>
|
||||
</ul>
|
||||
<div className="mt-4">
|
||||
<p className="w-full font-medium test-sm">{t("example_1")}</p>
|
||||
<div className="grid grid-cols-12 mt-2">
|
||||
<div className="col-span-5 test-sm text-default ltr:mr-2 rtl:ml-2">
|
||||
<p className="test-sm w-full font-medium">{t("example_1")}</p>
|
||||
<div className="mt-2 grid grid-cols-12">
|
||||
<div className="test-sm text-default col-span-5 ltr:mr-2 rtl:ml-2">
|
||||
{t("booking_question_identifier")}
|
||||
</div>
|
||||
<div className="col-span-7 test-sm text-emphasis">{t("company_size")}</div>
|
||||
<div className="w-full col-span-5 test-sm text-default">{t("variable")}</div>
|
||||
<div className="test-sm text-emphasis col-span-7">{t("company_size")}</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")
|
||||
.replace(/[^a-zA-Z0-9 ]/g, "")
|
||||
@@ -950,14 +975,14 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="w-full font-medium test-sm">{t("example_2")}</p>
|
||||
<div className="grid grid-cols-12 mt-2">
|
||||
<div className="col-span-5 test-sm text-default ltr:mr-2 rtl:ml-2">
|
||||
<p className="test-sm w-full font-medium">{t("example_2")}</p>
|
||||
<div className="mt-2 grid grid-cols-12">
|
||||
<div className="test-sm text-default col-span-5 ltr:mr-2 rtl:ml-2">
|
||||
{t("booking_question_identifier")}
|
||||
</div>
|
||||
<div className="col-span-7 test-sm text-emphasis">{t("what_help_needed")}</div>
|
||||
<div className="col-span-5 test-sm text-default">{t("variable")}</div>
|
||||
<div className="col-span-7 break-words test-sm text-emphasis">
|
||||
<div className="test-sm text-emphasis col-span-7">{t("what_help_needed")}</div>
|
||||
<div className="test-sm text-default col-span-5">{t("variable")}</div>
|
||||
<div className="test-sm text-emphasis col-span-7 break-words">
|
||||
{" "}
|
||||
{`{${t("what_help_needed")
|
||||
.replace(/[^a-zA-Z0-9 ]/g, "")
|
||||
@@ -969,7 +994,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter showDivider className="flex flex-row-reverse">
|
||||
<DialogFooter showDivider>
|
||||
<DialogClose color="primary" />
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { WorkflowActions, WorkflowTemplates, WorkflowTriggerEvents } from "@prisma/client";
|
||||
import { whatsappEventCancelledTemplate, whatsappEventCompletedTemplate, whatsappEventRescheduledTemplate, whatsappReminderTemplate } from "../lib/reminders/templates/whatsapp";
|
||||
import type { WorkflowTriggerEvents } from "@prisma/client";
|
||||
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) {
|
||||
return action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.SMS_NUMBER;
|
||||
@@ -10,46 +19,54 @@ export function isWhatsappAction(action: WorkflowActions) {
|
||||
}
|
||||
|
||||
export function isSMSOrWhatsappAction(action: WorkflowActions) {
|
||||
return isSMSAction(action) || isWhatsappAction(action)
|
||||
return isSMSAction(action) || isWhatsappAction(action);
|
||||
}
|
||||
|
||||
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 {
|
||||
switch(trigger) {
|
||||
switch (trigger) {
|
||||
case "NEW_EVENT":
|
||||
case "BEFORE_EVENT":
|
||||
return WorkflowTemplates.REMINDER
|
||||
return WorkflowTemplates.REMINDER;
|
||||
case "AFTER_EVENT":
|
||||
return WorkflowTemplates.COMPLETED
|
||||
return WorkflowTemplates.COMPLETED;
|
||||
case "EVENT_CANCELLED":
|
||||
return WorkflowTemplates.CANCELLED
|
||||
return WorkflowTemplates.CANCELLED;
|
||||
case "RESCHEDULE_EVENT":
|
||||
return WorkflowTemplates.RESCHEDULED
|
||||
return WorkflowTemplates.RESCHEDULED;
|
||||
default:
|
||||
return WorkflowTemplates.REMINDER
|
||||
return WorkflowTemplates.REMINDER;
|
||||
}
|
||||
}
|
||||
|
||||
export function getWhatsappTemplateFunction(template: WorkflowTemplates): typeof whatsappReminderTemplate {
|
||||
switch(template) {
|
||||
switch (template) {
|
||||
case "CANCELLED":
|
||||
return whatsappEventCancelledTemplate
|
||||
return whatsappEventCancelledTemplate;
|
||||
case "COMPLETED":
|
||||
return whatsappEventCompletedTemplate
|
||||
return whatsappEventCompletedTemplate;
|
||||
case "RESCHEDULED":
|
||||
return whatsappEventRescheduledTemplate
|
||||
return whatsappEventRescheduledTemplate;
|
||||
case "CUSTOM":
|
||||
case "REMINDER":
|
||||
return whatsappReminderTemplate
|
||||
return whatsappReminderTemplate;
|
||||
default:
|
||||
return whatsappReminderTemplate
|
||||
return whatsappReminderTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
export function getWhatsappTemplateForAction(action: WorkflowActions, template: WorkflowTemplates): string | null {
|
||||
const templateFunction = getWhatsappTemplateFunction(template)
|
||||
return templateFunction(true, action)
|
||||
export function getWhatsappTemplateForAction(
|
||||
action: WorkflowActions,
|
||||
template: WorkflowTemplates,
|
||||
timeFormat: TimeFormat
|
||||
): string | null {
|
||||
const templateFunction = getWhatsappTemplateFunction(template);
|
||||
return templateFunction(true, action, timeFormat);
|
||||
}
|
||||
|
||||
@@ -79,11 +79,13 @@ const noAlphanumericSenderIdSupport = [
|
||||
"+216",
|
||||
"+90",
|
||||
"+256",
|
||||
"+971",
|
||||
"+598",
|
||||
"+58",
|
||||
"+84",
|
||||
"+260",
|
||||
"+61",
|
||||
"+971",
|
||||
"+420",
|
||||
"+381",
|
||||
"+65",
|
||||
];
|
||||
|
||||
@@ -25,19 +25,16 @@ export const WORKFLOW_TEMPLATES = [
|
||||
WorkflowTemplates.REMINDER,
|
||||
WorkflowTemplates.CANCELLED,
|
||||
WorkflowTemplates.COMPLETED,
|
||||
WorkflowTemplates.RESCHEDULED
|
||||
WorkflowTemplates.RESCHEDULED,
|
||||
] as const;
|
||||
|
||||
export const BASIC_WORKFLOW_TEMPLATES = [
|
||||
WorkflowTemplates.CUSTOM,
|
||||
WorkflowTemplates.REMINDER,
|
||||
] as const;
|
||||
export const BASIC_WORKFLOW_TEMPLATES = [WorkflowTemplates.CUSTOM, WorkflowTemplates.REMINDER] as const;
|
||||
|
||||
export const WHATSAPP_WORKFLOW_TEMPLATES = [
|
||||
WorkflowTemplates.REMINDER,
|
||||
WorkflowTemplates.COMPLETED,
|
||||
WorkflowTemplates.CANCELLED,
|
||||
WorkflowTemplates.RESCHEDULED
|
||||
WorkflowTemplates.RESCHEDULED,
|
||||
] as const;
|
||||
|
||||
export const DYNAMIC_TEXT_VARIABLES = [
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { WorkflowStep } from "@prisma/client";
|
||||
|
||||
import { isSMSOrWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { WorkflowActions } from "@calcom/prisma/enums";
|
||||
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 {
|
||||
if (steps.length === 0) {
|
||||
|
||||
@@ -3,7 +3,13 @@ import type { TFunction } from "next-i18next";
|
||||
import { WorkflowActions } from "@calcom/prisma/enums";
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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 { label: t(`${template.toLowerCase()}`), value: template };
|
||||
}) as { label: string; value: any }[];
|
||||
|
||||
@@ -104,13 +104,20 @@ export const scheduleEmailReminder = async (
|
||||
? evt.attendees[0].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.emailBody = customTemplate(emailBody, variables, locale, hideBranding).html;
|
||||
emailContent.emailBody = customTemplate(
|
||||
emailBody,
|
||||
variables,
|
||||
locale,
|
||||
evt.organizer.timeFormat,
|
||||
hideBranding
|
||||
).html;
|
||||
} else if (template === WorkflowTemplates.REMINDER) {
|
||||
emailContent = emailReminderTemplate(
|
||||
false,
|
||||
action,
|
||||
evt.organizer.timeFormat,
|
||||
startTime,
|
||||
endTime,
|
||||
evt.title,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Workflow, WorkflowsOnEventTypes, WorkflowStep } from "@prisma/client";
|
||||
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 { WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
||||
import { WorkflowActions } from "@calcom/prisma/enums";
|
||||
@@ -10,8 +11,6 @@ import { scheduleEmailReminder } from "./emailReminderManager";
|
||||
import { scheduleSMSReminder } from "./smsReminderManager";
|
||||
import { scheduleWhatsappReminder } from "./whatsappReminderManager";
|
||||
|
||||
import { isWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
|
||||
|
||||
type ExtendedCalendarEvent = CalendarEvent & {
|
||||
metadata?: { videoCallUrl: string | undefined };
|
||||
eventType: { slug?: string };
|
||||
@@ -113,7 +112,8 @@ export const scheduleWorkflowReminders = async (args: ScheduleWorkflowRemindersA
|
||||
hideBranding
|
||||
);
|
||||
} 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(
|
||||
evt,
|
||||
sendTo,
|
||||
@@ -208,7 +208,8 @@ export const sendCancelledReminders = async (args: SendCancelledRemindersArgs) =
|
||||
hideBranding
|
||||
);
|
||||
} 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(
|
||||
evt,
|
||||
sendTo,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user