Merge branch 'main' into testE2E-timezone

This commit is contained in:
GitStart-Cal.com 2023-11-29 22:04:23 +05:45 committed by GitHub
commit 0ad9e3fabb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 648 additions and 2486 deletions

View File

@ -266,7 +266,7 @@ CALCOM_WEBHOOK_SECRET=""
CALCOM_WEBHOOK_HEADER_NAME="calcom-webhook-secret"
CALCOM_CREDENTIAL_SYNC_ENDPOINT=""
# Key should match on Cal.com and your application
# must be 32 bytes for AES256 encryption algorithm
# must be 24 bytes for AES256 encryption algorithm
# You can use: `openssl rand -base64 24` to generate one
CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY=""

View File

@ -32,6 +32,7 @@ type AppListCardProps = {
invalidCredential?: boolean;
children?: ReactNode;
credentialOwner?: CredentialOwner;
className?: string;
} & ShouldHighlight;
const schema = z.object({ hl: z.string().optional() });
@ -50,6 +51,7 @@ export default function AppListCard(props: AppListCardProps) {
invalidCredential,
children,
credentialOwner,
className,
} = props;
const {
data: { hl },
@ -83,7 +85,7 @@ export default function AppListCard(props: AppListCardProps) {
}, [highlight, pathname, router, searchParams, shouldHighlight]);
return (
<div className={classNames(highlight && "dark:bg-muted bg-yellow-100")}>
<div className={classNames(highlight && "dark:bg-muted bg-yellow-100", className)}>
<div className="flex items-center gap-x-3 px-4 py-4 sm:px-6">
{logo ? (
<img

View File

@ -14,8 +14,9 @@ import {
List,
AppSkeletonLoader as SkeletonLoader,
ShellSubHeading,
Label,
} from "@calcom/ui";
import { Calendar, Plus } from "@calcom/ui/components/icon";
import { Calendar } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
@ -27,6 +28,7 @@ type Props = {
onChanged: () => unknown | Promise<unknown>;
fromOnboarding?: boolean;
destinationCalendarId?: string;
isLoading?: boolean;
};
function CalendarList(props: Props) {
@ -70,8 +72,9 @@ function ConnectedCalendarsList(props: Props) {
const { t } = useLocale();
const query = trpc.viewer.connectedCalendars.useQuery(undefined, {
suspense: true,
refetchOnWindowFocus: false,
});
const { fromOnboarding } = props;
const { fromOnboarding, isLoading } = props;
return (
<QueryCell
query={query}
@ -82,74 +85,94 @@ function ConnectedCalendarsList(props: Props) {
}
return (
<List>
{data.connectedCalendars.map((item) => (
<Fragment key={item.credentialId}>
{item.calendars ? (
<AppListCard
shouldHighlight
slug={item.integration.slug}
title={item.integration.name}
logo={item.integration.logo}
description={item.primary?.email ?? item.integration.description}
actions={
<div className="flex w-32 justify-end">
<DisconnectIntegration
credentialId={item.credentialId}
trashIcon
onSuccess={props.onChanged}
buttonProps={{ className: "border border-default" }}
/>
</div>
}>
<div className="border-subtle border-t">
{!fromOnboarding && (
<>
<p className="text-subtle px-5 pt-4 text-sm">{t("toggle_calendars_conflict")}</p>
<ul className="space-y-4 px-5 py-4">
{item.calendars.map((cal) => (
<CalendarSwitch
key={cal.externalId}
externalId={cal.externalId}
title={cal.name || "Nameless calendar"}
name={cal.name || "Nameless calendar"}
type={item.integration.type}
isChecked={cal.isSelected}
destination={cal.externalId === props.destinationCalendarId}
credentialId={cal.credentialId}
/>
))}
</ul>
</>
)}
<div className="border-subtle mt-6 rounded-lg border">
<div className="border-subtle border-b p-6">
<div className="flex items-center justify-between">
<div>
<h4 className="text-emphasis text-base font-semibold leading-5">
{t("check_for_conflicts")}
</h4>
<p className="text-default text-sm leading-tight">{t("select_calendars")}</p>
</div>
<div className="flex flex-col xl:flex-row xl:space-x-5">
{!!data.connectedCalendars.length && (
<div className="flex items-center">
<AdditionalCalendarSelector isLoading={isLoading} />
</div>
</AppListCard>
) : (
<Alert
severity="warning"
title={t("something_went_wrong")}
message={
<span>
<Link href={`/apps/${item.integration.slug}`}>{item.integration.name}</Link>:{" "}
{t("calendar_error")}
</span>
}
iconClassName="h-10 w-10 ml-2 mr-1 mt-0.5"
actions={
<div className="flex w-32 justify-end md:pr-1">
<DisconnectIntegration
credentialId={item.credentialId}
trashIcon
onSuccess={props.onChanged}
buttonProps={{ className: "border border-default" }}
/>
)}
</div>
</div>
</div>
<List noBorderTreatment className="p-6 pt-2">
{data.connectedCalendars.map((item) => (
<Fragment key={item.credentialId}>
{item.calendars ? (
<AppListCard
shouldHighlight
slug={item.integration.slug}
title={item.integration.name}
logo={item.integration.logo}
description={item.primary?.email ?? item.integration.description}
className="border-subtle mt-4 rounded-lg border"
actions={
<div className="flex w-32 justify-end">
<DisconnectIntegration
credentialId={item.credentialId}
trashIcon
onSuccess={props.onChanged}
buttonProps={{ className: "border border-default" }}
/>
</div>
}>
<div className="border-subtle border-t">
{!fromOnboarding && (
<>
<p className="text-subtle px-5 pt-4 text-sm">{t("toggle_calendars_conflict")}</p>
<ul className="space-y-4 px-5 py-4">
{item.calendars.map((cal) => (
<CalendarSwitch
key={cal.externalId}
externalId={cal.externalId}
title={cal.name || "Nameless calendar"}
name={cal.name || "Nameless calendar"}
type={item.integration.type}
isChecked={cal.isSelected}
destination={cal.externalId === props.destinationCalendarId}
credentialId={cal.credentialId}
/>
))}
</ul>
</>
)}
</div>
}
/>
)}
</Fragment>
))}
</List>
</AppListCard>
) : (
<Alert
severity="warning"
title={t("something_went_wrong")}
message={
<span>
<Link href={`/apps/${item.integration.slug}`}>{item.integration.name}</Link>:{" "}
{t("calendar_error")}
</span>
}
iconClassName="h-10 w-10 ml-2 mr-1 mt-0.5"
actions={
<div className="flex w-32 justify-end md:pr-1">
<DisconnectIntegration
credentialId={item.credentialId}
trashIcon
onSuccess={props.onChanged}
buttonProps={{ className: "border border-default" }}
/>
</div>
}
/>
)}
</Fragment>
))}
</List>
</div>
);
}}
/>
@ -187,42 +210,28 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
{!!data.connectedCalendars.length || !!installedCalendars.data?.items.length ? (
<>
{heading && (
<div className="border-default flex flex-col gap-6 rounded-md border p-7">
<ShellSubHeading
title={t("calendar")}
subtitle={t("installed_app_calendar_description")}
className="mb-0 flex flex-wrap items-center gap-4 sm:flex-nowrap md:mb-3 md:gap-0"
actions={
<div className="flex flex-col xl:flex-row xl:space-x-5">
{!!data.connectedCalendars.length && (
<div className="flex items-center">
<AdditionalCalendarSelector isLoading={mutation.isLoading} />
</div>
)}
</div>
}
/>
<div className="bg-muted border-subtle flex justify-between rounded-md border p-4">
<div className="flex w-full flex-col items-start gap-4 md:flex-row md:items-center">
<div className="bg-default border-subtle relative rounded-md border p-1.5">
<Calendar className="text-default h-8 w-8" strokeWidth="1" />
<Plus
className="text-emphasis absolute left-4 top-1/2 ml-0.5 mt-[1px] h-2 w-2"
strokeWidth="4"
/>
</div>
<div className="md:w-6/12">
<h1 className="text-emphasis text-sm font-semibold">{t("create_events_on")}</h1>
<p className="text-default text-sm font-normal">{t("set_calendar")}</p>
</div>
<div className="justify-end md:w-6/12">
<DestinationCalendarSelector
onChange={mutation.mutate}
hidePlaceholder
isLoading={mutation.isLoading}
value={data.destinationCalendar?.externalId}
hideAdvancedText
/>
<>
<div className="border-subtle mb-6 mt-8 rounded-lg border">
<div className="p-6">
<h2 className="text-emphasis mb-1 text-base font-bold leading-5 tracking-wide">
{t("add_to_calendar")}
</h2>
<p className="text-subtle text-sm leading-tight">
{t("add_to_calendar_description")}
</p>
</div>
<div className="border-t">
<div className="border-subtle flex w-full flex-col space-y-3 border-y-0 p-6">
<div>
<Label className="text-default mb-0 font-medium">{t("add_events_to")}</Label>
<DestinationCalendarSelector
hidePlaceholder
value={data.destinationCalendar?.externalId}
onChange={mutation.mutate}
isLoading={mutation.isLoading}
/>
</div>
</div>
</div>
</div>
@ -230,8 +239,9 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
onChanged={onChanged}
fromOnboarding={fromOnboarding}
destinationCalendarId={data.destinationCalendar?.externalId}
isLoading={mutation.isLoading}
/>
</div>
</>
)}
</>
) : fromOnboarding ? (

View File

@ -262,15 +262,21 @@ function BookingListItem(booking: BookingItemProps) {
const title = booking.title;
const showRecordingsButtons = !!(booking.isRecorded && isPast && isConfirmed);
const showViewRecordingsButton = !!(booking.isRecorded && isPast && isConfirmed);
const showCheckRecordingButton =
isPast &&
isConfirmed &&
!booking.isRecorded &&
(!booking.location || booking.location === "integrations:daily" || booking?.location?.trim() === "");
const showRecordingActions: ActionType[] = [
{
id: "view_recordings",
label: t("view_recordings"),
label: showCheckRecordingButton ? t("check_for_recordings") : t("view_recordings"),
onClick: () => {
setViewRecordingsDialogIsOpen(true);
},
color: showCheckRecordingButton ? "secondary" : "primary",
disabled: mutation.isLoading,
},
];
@ -298,7 +304,7 @@ function BookingListItem(booking: BookingItemProps) {
paymentCurrency={booking.payment[0].currency}
/>
)}
{showRecordingsButtons && (
{(showViewRecordingsButton || showCheckRecordingButton) && (
<ViewRecordingsDialog
booking={booking}
isOpenDialog={viewRecordingsDialogIsOpen}
@ -478,7 +484,9 @@ function BookingListItem(booking: BookingItemProps) {
</>
) : null}
{isPast && isPending && !isConfirmed ? <TableActions actions={bookedActions} /> : null}
{showRecordingsButtons && <TableActions actions={showRecordingActions} />}
{(showViewRecordingsButton || showCheckRecordingButton) && (
<TableActions actions={showRecordingActions} />
)}
{isCancelled && booking.rescheduled && (
<div className="hidden h-full items-center md:flex">
<RequestSentMessage />

View File

@ -130,7 +130,6 @@
"tailwindcss-radix": "^2.6.0",
"turndown": "^7.1.1",
"uuid": "^8.3.2",
"web3": "^1.7.5",
"zod": "^3.22.2"
},
"devDependencies": {

View File

@ -54,8 +54,8 @@ const IntegrationsContainer = ({
automation: Share2,
analytics: BarChart,
payment: CreditCard,
web3: BarChart, // deprecated
other: Grid,
web3: CreditCard, // deprecated
video: Video, // deprecated
messaging: Mail,
crm: Contact,

View File

@ -1,37 +1,12 @@
import { Trans } from "next-i18next";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Fragment, useState, useEffect } from "react";
import { Fragment } from "react";
import DisconnectIntegration from "@calcom/features/apps/components/DisconnectIntegration";
import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch";
import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector";
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import {
Alert,
Badge,
Button,
EmptyScreen,
List,
ListItem,
ListItemText,
ListItemTitle,
Meta,
SkeletonButton,
SkeletonContainer,
SkeletonText,
showToast,
Label,
} from "@calcom/ui";
import { Plus, Calendar } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
import { Button, Meta, SkeletonButton, SkeletonContainer, SkeletonText } from "@calcom/ui";
import { Plus } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import { CalendarListContainer } from "@components/apps/CalendarListContainer";
const SkeletonLoader = () => {
return (
@ -62,37 +37,6 @@ const AddCalendarButton = () => {
const CalendarsView = () => {
const { t } = useLocale();
const router = useRouter();
const utils = trpc.useContext();
const query = trpc.viewer.connectedCalendars.useQuery();
const [selectedDestinationCalendarOption, setSelectedDestinationCalendar] = useState<{
integration: string;
externalId: string;
} | null>(null);
useEffect(() => {
if (query?.data?.destinationCalendar) {
setSelectedDestinationCalendar({
integration: query.data.destinationCalendar.integration,
externalId: query.data.destinationCalendar.externalId,
});
}
}, [query?.isLoading, query?.data?.destinationCalendar]);
const mutation = trpc.viewer.setDestinationCalendar.useMutation({
async onSettled() {
await utils.viewer.connectedCalendars.invalidate();
},
onSuccess: async () => {
showToast(t("calendar_updated_successfully"), "success");
},
onError: () => {
showToast(t("unexpected_error_try_again"), "error");
},
});
return (
<>
@ -102,167 +46,9 @@ const CalendarsView = () => {
CTA={<AddCalendarButton />}
borderInShellHeader={false}
/>
<QueryCell
query={query}
customLoader={<SkeletonLoader />}
success={({ data }) => {
const isDestinationUpdateBtnDisabled =
selectedDestinationCalendarOption?.externalId === query?.data?.destinationCalendar?.externalId;
return data.connectedCalendars.length ? (
<div>
<div className="border-subtle mt-8 rounded-t-lg border px-4 py-6 sm:px-6">
<h2 className="text-emphasis mb-1 text-base font-bold leading-5 tracking-wide">
{t("add_to_calendar")}
</h2>
<p className="text-subtle text-sm leading-tight">{t("add_to_calendar_description")}</p>
</div>
<div className="border-subtle flex w-full flex-col space-y-3 border border-x border-y-0 px-4 py-6 sm:px-6">
<div>
<Label className="text-default mb-0 font-medium">{t("add_events_to")}</Label>
<DestinationCalendarSelector
hidePlaceholder
value={selectedDestinationCalendarOption?.externalId}
onChange={(option) => {
setSelectedDestinationCalendar(option);
}}
isLoading={mutation.isLoading}
/>
</div>
</div>
<SectionBottomActions align="end">
<Button
loading={mutation.isLoading}
disabled={isDestinationUpdateBtnDisabled}
color="primary"
onClick={() => {
if (selectedDestinationCalendarOption) mutation.mutate(selectedDestinationCalendarOption);
}}>
{t("update")}
</Button>
</SectionBottomActions>
<div className="border-subtle mt-8 rounded-t-lg border px-4 py-6 sm:px-6">
<h4 className="text-emphasis text-base font-semibold leading-5">
{t("check_for_conflicts")}
</h4>
<p className="text-default text-sm leading-tight">{t("select_calendars")}</p>
</div>
<List
className="border-subtle flex flex-col gap-6 rounded-b-lg border border-t-0 p-6"
noBorderTreatment>
{data.connectedCalendars.map((item) => (
<Fragment key={item.credentialId}>
{item.error && item.error.message && (
<Alert
severity="warning"
key={item.credentialId}
title={t("calendar_connection_fail")}
message={item.error.message}
className="mb-4 mt-4"
actions={
<>
{/* @TODO: add a reconnect button, that calls add api and delete old credential */}
<DisconnectIntegration
credentialId={item.credentialId}
trashIcon
onSuccess={() => query.refetch()}
buttonProps={{
className: "border border-default py-[2px]",
color: "secondary",
}}
/>
</>
}
/>
)}
{item?.error === undefined && item.calendars && (
<ListItem className="flex-col rounded-lg">
<div className="flex w-full flex-1 items-center space-x-3 p-4 rtl:space-x-reverse">
{
// eslint-disable-next-line @next/next/no-img-element
item.integration.logo && (
<img
className={classNames(
"h-10 w-10",
item.integration.logo.includes("-dark") && "dark:invert"
)}
src={item.integration.logo}
alt={item.integration.title}
/>
)
}
<div className="flex-grow truncate pl-2">
<ListItemTitle component="h3" className="mb-1 space-x-2 rtl:space-x-reverse">
<Link href={`/apps/${item.integration.slug}`}>
{item.integration.name || item.integration.title}
</Link>
{data?.destinationCalendar?.credentialId === item.credentialId && (
<Badge variant="green">Default</Badge>
)}
</ListItemTitle>
<ListItemText component="p">{item.integration.description}</ListItemText>
</div>
<div>
<DisconnectIntegration
trashIcon
credentialId={item.credentialId}
buttonProps={{ className: "border border-default" }}
/>
</div>
</div>
<div className="border-subtle w-full border-t">
<p className="text-subtle px-2 pt-4 text-sm">{t("toggle_calendars_conflict")}</p>
<ul className="space-y-4 p-4">
{item.calendars.map((cal) => (
<CalendarSwitch
key={cal.externalId}
credentialId={cal.credentialId}
externalId={cal.externalId}
title={cal.name || "Nameless calendar"}
name={cal.name || "Nameless calendar"}
type={item.integration.type}
isChecked={
cal.isSelected || cal.externalId === data?.destinationCalendar?.externalId
}
/>
))}
</ul>
</div>
</ListItem>
)}
</Fragment>
))}
</List>
</div>
) : (
<EmptyScreen
Icon={Calendar}
headline={t("no_calendar_installed")}
description={t("no_calendar_installed_description")}
buttonText={t("add_a_calendar")}
buttonOnClick={() => router.push("/apps/categories/calendar")}
className="mt-6"
/>
);
}}
error={() => {
return (
<Alert
message={
<Trans i18nKey="fetching_calendars_error">
An error ocurred while fetching your Calendars.
<a className="cursor-pointer underline" onClick={() => query.refetch()}>
try again
</a>
.
</Trans>
}
severity="error"
/>
);
}}
/>
<div className="mt-8">
<CalendarListContainer />
</div>
</>
);
};

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "سيوفر {{appName}} رابطًا للاجتماع عبر Tandem.",
"cal_provide_video_meeting_url": "سيوفر {{appName}} رابطًا للاجتماع عبر الفيديو على Daily.",
"cal_provide_jitsi_meeting_url": "سنوفر لك رابطًا للاجتماع عبر Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "سيوفر {{appName}} رابطًا للاجتماع عبر الفيديو على Huddle01 web3.",
"cal_provide_huddle01_meeting_url": "سيوفر {{appName}} رابطًا للاجتماع عبر الفيديو على Huddle01.",
"cal_provide_teams_meeting_url": "سيوفر {{appName}} عنوان URL لاجتماعات MS Teams. ملاحظة: يجب أن يكون لديك حساب عمل أو حساب مدرسة",
"require_payment": "يلزم الدفع",
"you_need_to_add_a_name": "تحتاج إلى إضافة اسم",
@ -904,7 +904,6 @@
"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": "قم بتعيين التقويمات للتحقق من وجود تعارضات لمنع الحجوزات المزدوجة.",
@ -913,7 +912,6 @@
"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": "التحليلات",
@ -1304,7 +1302,6 @@
"profile_picture": "صورة الملف الشخصي",
"upload": "تحميل",
"add_profile_photo": "إضافة صورة الملف الشخصي",
"web3": "Web3",
"token_address": "عنوان الرمز المميز",
"blockchain": "سلسلة الكتل",
"old_password": "كلمة مرور قديمة",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "توصيل تطبيقات الأتمتة",
"connect_analytics_apps": "توصيل تطبيقات التحليلات",
"connect_other_apps": "ربط تطبيقات أخرى",
"connect_web3_apps": "ربط تطبيقات web3",
"connect_messaging_apps": "ربط تطبيقات المراسلة",
"connect_crm_apps": "ربط تطبيقات CRM",
"current_step_of_total": "الخطوة {{currentStep}} من {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} poskytne URL Tandem meetingu.",
"cal_provide_video_meeting_url": "{{appName}} poskytne URL Daily video meetingu.",
"cal_provide_jitsi_meeting_url": "{{appName}} poskytne URL Jitsi Meet video meetingu.",
"cal_provide_huddle01_meeting_url": "{{appName}} poskytne URL Huddle01 web3 video meetingu.",
"cal_provide_huddle01_meeting_url": "{{appName}} poskytne URL Huddle01 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",
@ -904,7 +904,6 @@
"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.",
@ -913,7 +912,6 @@
"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",
@ -1304,7 +1302,6 @@
"profile_picture": "Profilová fotka",
"upload": "Nahrát",
"add_profile_photo": "Přidat profilovou fotku",
"web3": "Web3",
"token_address": "Adresa tokenu",
"blockchain": "Blockchain",
"old_password": "Staré heslo",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Připojit aplikace pro automatizaci",
"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}}",

View File

@ -681,7 +681,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} angiver en URL-adresse for Tandem-mødet.",
"cal_provide_video_meeting_url": "{{appName}} angiver en URL-adresse for videomødet.",
"cal_provide_jitsi_meeting_url": "Vi genererer en Jitsi Meet URL til dig.",
"cal_provide_huddle01_meeting_url": "{{appName}} vil levere en Huddle01 web3 videomøde-URL.",
"cal_provide_huddle01_meeting_url": "{{appName}} vil levere en Huddle01 videomøde-URL.",
"cal_provide_teams_meeting_url": "{{appName}} vil levere en MS Teams møde URL. BEMÆRK: SKAL HA EN ARBEJDS- ELLER SKOLE KONTO",
"require_payment": "Kræv Betaling",
"commission_per_transaction": "provision pr. transaktion",
@ -770,13 +770,11 @@
"no_category_apps_description_analytics": "Tilføj en analyseapp til dine bookingsider",
"no_category_apps_description_automation": "Tilføj en automatiseringsapp til brug",
"no_category_apps_description_other": "Tilføj enhver anden type app for at gøre alle mulige ting",
"no_category_apps_description_web3": "Tilføj en web3 app til dine bookingsider",
"installed_app_calendar_description": "Indstil kalenderne til at tjekke for konflikter, for at forhindre dobbeltbookinger.",
"installed_app_payment_description": "Indstil hvilke betalingsbehandlingstjenester der skal bruges, når du opkræver betaling fra dine kunder.",
"installed_app_analytics_description": "Indstil hvilke analyseapps der skal bruges til dine bookingsider",
"installed_app_other_description": "Alle dine installerede apps fra andre kategorier.",
"installed_app_automation_description": "Indstil hvilke automatiseringsapps der skal bruges",
"installed_app_web3_description": "Indstil hvilke web3 apps der skal bruges til dine bookingsider",
"analytics": "Analyser",
"empty_installed_apps_headline": "Ingen apps installeret",
"empty_installed_apps_description": "Apps giver dig mulighed for at forbedre din arbejdsgang og forbedre dit planlægningsliv betydeligt.",
@ -1132,7 +1130,6 @@
"profile_picture": "Profilbillede",
"upload": "Upload",
"add_profile_photo": "Tilføj profilbillede",
"web3": "Web3",
"token_address": "Token Adresse",
"blockchain": "Blockchain",
"old_password": "Gammel adgangskode",
@ -1171,7 +1168,6 @@
"connect_automation_apps": "Tilslut automatiseringsapps",
"connect_analytics_apps": "Tilslut analyseapps",
"connect_other_apps": "Tilslut andre apps",
"connect_web3_apps": "Tilslut web3 apps",
"current_step_of_total": "Trin {{currentStep}} af {{maxSteps}}",
"add_variable": "Tilføj variabel",
"custom_phone_number": "Brugerdefineret telefonnummer",
@ -1534,5 +1530,7 @@
"this_will_be_the_placeholder": "Dette vil være pladsholderen",
"verification_code": "Bekræftelseskode",
"verify": "Bekræft",
"confirm_your_details": "Bekræft dine oplysninger",
"overlay_my_calendar": "Vis min kalender",
"need_help": "Brug for hjælp?"
}

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} wird eine Tandem Meeting URL zur Verfügung stellen.",
"cal_provide_video_meeting_url": "{{appName}} wird eine Video-Meeting URL zur Verfügung stellen.",
"cal_provide_jitsi_meeting_url": "Cal stellt eine Jitsi Meet URL zur Verfügung.",
"cal_provide_huddle01_meeting_url": "{{appName}} wird eine Huddle01 web3 Video-Meeting URL zur Verfügung stellen.",
"cal_provide_huddle01_meeting_url": "{{appName}} wird eine Huddle01 Video-Meeting URL zur Verfügung stellen.",
"cal_provide_teams_meeting_url": "{{appName}} wird eine MS Teams Meeting-URL zur Verfügung stellen. HINWEIS: SIE BRAUCHEN EIN BERUFS- ODER SCHULKONTO",
"require_payment": "Zahlung erforderlich",
"you_need_to_add_a_name": "Sie müssen einen Namen hinzufügen",
@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Fügen Sie eine Analyse-App für Ihre Buchungsseiten hinzu",
"no_category_apps_description_automation": "Fügen Sie eine Automatisierungs-App hinzu, die verwendet werden soll",
"no_category_apps_description_other": "Füge jede beliebige andere Art von App hinzu, um alle möglichen Dinge zu tun",
"no_category_apps_description_web3": "Fügen Sie eine web3-App für Ihre Buchungsseiten hinzu",
"no_category_apps_description_messaging": "Fügen Sie eine Nachrichten-App hinzu, um benutzerdefinierte Benachrichtigungen und Erinnerungen einzurichten",
"no_category_apps_description_crm": "Fügen Sie eine CRM-App hinzu, um einen Überblick über die Personen zu behalten, mit denen Sie sich getroffen haben",
"installed_app_calendar_description": "Legen Sie den/die Kalender in denen nach Konflikten gesucht werden sollen fest, um Doppelbuchungen zu vermeiden.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Alle von Ihnen installierten Apps aus anderen Kategorien.",
"installed_app_conferencing_description": "Konfigurieren Sie, welche Konferenz-Apps verwendet werden sollen",
"installed_app_automation_description": "Konfigurieren Sie, welche Automatisierungs-Apps verwendet werden sollen",
"installed_app_web3_description": "Konfigurieren Sie, welche web3-Apps für Ihre Buchungsseiten verwendet werden sollen",
"installed_app_messaging_description": "Konfigurieren Sie zur Einrichtung benutzerdefinierter Benachrichtigungen und Erinnerungen, welche Nachrichten-Apps verwendet werden sollen",
"installed_app_crm_description": "Konfigurieren Sie, welche CRM-Apps verwendet werden sollen, um einen Überblick über die Personen zu behalten, mit denen Sie sich getroffen haben",
"analytics": "Analyse",
@ -1304,7 +1302,6 @@
"profile_picture": "Profilbild",
"upload": "Upload",
"add_profile_photo": "Profilbild hinzufügen",
"web3": "Web3",
"token_address": "Adresse des Token",
"blockchain": "Blockchain",
"old_password": "Altes Passwort",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Automatisierungs-Apps verbinden",
"connect_analytics_apps": "Analyse-Apps verbinden",
"connect_other_apps": "Andere Apps verbinden",
"connect_web3_apps": "web3-Apps verbinden",
"connect_messaging_apps": "Nachrichten-Apps verbinden",
"connect_crm_apps": "CRM-Apps verbinden",
"current_step_of_total": "Schritt {{currentStep}} von {{maxSteps}}",

View File

@ -818,7 +818,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} will provide a Tandem meeting URL.",
"cal_provide_video_meeting_url": "{{appName}} will provide a video meeting URL.",
"cal_provide_jitsi_meeting_url": "We will generate a Jitsi Meet URL for you.",
"cal_provide_huddle01_meeting_url": "{{appName}} will provide a Huddle01 web3 video meeting URL.",
"cal_provide_huddle01_meeting_url": "{{appName}} will provide a Huddle01 video meeting URL.",
"cal_provide_teams_meeting_url": "{{appName}} will provide a MS Teams meeting URL. NOTE: MUST HAVE A WORK OR SCHOOL ACCOUNT",
"require_payment": "Require Payment",
"you_need_to_add_a_name": "You need to add a name",
@ -922,7 +922,6 @@
"no_category_apps_description_analytics": "Add an analytics app for your booking pages",
"no_category_apps_description_automation": "Add an automation app to use",
"no_category_apps_description_other": "Add any other type of app to do all sorts of things",
"no_category_apps_description_web3": "Add a web3 app for your booking pages",
"no_category_apps_description_messaging": "Add a messaging app to set up custom notifications & reminders",
"no_category_apps_description_crm": "Add a CRM app to keep track of who you've met with",
"installed_app_calendar_description": "Set the calendars to check for conflicts to prevent double bookings.",
@ -931,7 +930,6 @@
"installed_app_other_description": "All your installed apps from other categories.",
"installed_app_conferencing_description": "Configure which conferencing apps to use",
"installed_app_automation_description": "Configure which automation apps to use",
"installed_app_web3_description": "Configure which web3 apps to use for your booking pages",
"installed_app_messaging_description": "Configure which messaging apps to use for setting up custom notifications & reminders",
"installed_app_crm_description": "Configure which CRM apps to use for keeping track of who you've met with",
"analytics": "Analytics",
@ -1324,7 +1322,6 @@
"profile_picture": "Profile Picture",
"upload": "Upload",
"add_profile_photo": "Add profile photo",
"web3": "Web3",
"token_address": "Token Address",
"blockchain": "Blockchain",
"old_password": "Old password",
@ -1366,7 +1363,6 @@
"connect_automation_apps": "Connect automation apps",
"connect_analytics_apps": "Connect analytics apps",
"connect_other_apps": "Connect other apps",
"connect_web3_apps": "Connect web3 apps",
"connect_messaging_apps": "Connect messaging apps",
"connect_crm_apps": "Connect CRM apps",
"current_step_of_total": "Step {{currentStep}} of {{maxSteps}}",

View File

@ -904,7 +904,6 @@
"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.",
@ -913,7 +912,6 @@
"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",
@ -1304,7 +1302,6 @@
"profile_picture": "Imagen de perfil",
"upload": "Cargar",
"add_profile_photo": "Agregar foto de perfil",
"web3": "Web3",
"token_address": "Dirección del token",
"blockchain": "Blockchain",
"old_password": "Contraseña anterior",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Conecte aplicaciones de automatización",
"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}}",

View File

@ -679,7 +679,6 @@
"profile_picture": "Profileko irudia",
"upload": "Kargatu",
"add_profile_photo": "Gehitu profileko argazkia",
"web3": "Web3",
"old_password": "Pasahitz zaharra",
"secure_password": "Zure pasahitz berri super segurua",
"error_updating_password": "Errorea pasahitza eguneratzean",

View File

@ -67,6 +67,7 @@
"cannot_repackage_codebase": "Vous ne pouvez pas restructurer ou vendre la base de code",
"acquire_license": "Obtenez une licence commerciale pour supprimer ces termes en envoyant un e-mail",
"terms_summary": "Résumé des conditions",
"signing_up_terms": "En vous inscrivant, vous acceptez nos <2>Conditions d'utilisation</2> et notre <3>Politique de confidentialité</3>.",
"open_env": "Ouvrez le fichier .env et acceptez notre licence",
"env_changed": "J'ai modifié mon fichier .env",
"accept_license": "Accepter la licence",
@ -229,6 +230,7 @@
"reset_your_password": "Définissez votre nouveau mot de passe avec les instructions envoyées à votre adresse e-mail.",
"email_change": "Reconnectez-vous avec votre nouvelle adresse e-mail et votre nouveau mot de passe.",
"create_your_account": "Créez votre compte",
"create_your_calcom_account": "Créez votre compte Cal.com",
"sign_up": "S'inscrire",
"youve_been_logged_out": "Vous avez été déconnecté",
"hope_to_see_you_soon": "Nous espérons vous revoir bientôt !",
@ -266,6 +268,9 @@
"nearly_there_instructions": "Pour finir, une brève description de vous et une photo vous aideront vraiment à obtenir des réservations et à faire savoir aux gens avec qui ils prennent rendez-vous.",
"set_availability_instructions": "Définissez des plages de temps pendant lesquelles vous êtes disponible de manière récurrente. Vous pourrez en créer d'autres ultérieurement et les assigner à différents calendriers.",
"set_availability": "Définissez vos disponibilités",
"set_availbility_description": "Définissez des horaires pour les périodes où vous souhaitez être réservé.",
"share_a_link_or_embed": "Partagez un lien ou une intégration",
"share_a_link_or_embed_description": "Partagez votre lien ou intégration {{appName}} sur votre site.",
"availability_settings": "Paramètres de disponibilité",
"continue_without_calendar": "Continuer sans calendrier",
"continue_with": "Continuer avec {{appName}}",
@ -800,7 +805,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} fournira un lien de rendez-vous Tandem.",
"cal_provide_video_meeting_url": "{{appName}} fournira un lien de rendez-vous vidéo.",
"cal_provide_jitsi_meeting_url": "Nous générerons un lien de réunion Jitsi Meet pour vous.",
"cal_provide_huddle01_meeting_url": "{{appName}} fournira un lien de rendez-vous vidéo Huddle01 web3.",
"cal_provide_huddle01_meeting_url": "{{appName}} fournira un lien de rendez-vous vidéo Huddle01.",
"cal_provide_teams_meeting_url": "{{appName}} fournira un lien de rendez-vous MS Teams. NOTE : IL FAUT AVOIR UN COMPTE PROFESSIONNEL OU SCOLAIRE",
"require_payment": "Exiger un paiement",
"you_need_to_add_a_name": "Vous devez ajouter un nom",
@ -904,7 +909,6 @@
"no_category_apps_description_analytics": "Ajoutez une application d'analyse pour vos pages de réservation.",
"no_category_apps_description_automation": "Ajoutez une application d'automatisation.",
"no_category_apps_description_other": "Ajoutez n'importe quel autre type d'application pour faire toutes sortes de choses.",
"no_category_apps_description_web3": "Ajoutez une application Web3 pour vos pages de réservation.",
"no_category_apps_description_messaging": "Ajoutez une application de messagerie pour configurer des notifications et des rappels personnalisés.",
"no_category_apps_description_crm": "Ajoutez une application de CRM pour garder une trace des personnes que vous avez rencontrées.",
"installed_app_calendar_description": "Définissez les calendriers pour vérifier les conflits afin d'éviter les doubles réservations.",
@ -913,7 +917,6 @@
"installed_app_other_description": "Toutes vos applications installées à partir d'autres catégories.",
"installed_app_conferencing_description": "Configurez les applications de conférence à utiliser.",
"installed_app_automation_description": "Configurez les applications d'automatisation à utiliser.",
"installed_app_web3_description": "Configurez les applications Web3 à utiliser pour vos pages de réservation.",
"installed_app_messaging_description": "Configurez les applications de messagerie à utiliser pour configurer des notifications et des rappels personnalisés.",
"installed_app_crm_description": "Configurez les applications de CRM à utiliser pour garder une trace des personnes que vous avez rencontrées.",
"analytics": "Analytiques",
@ -1036,6 +1039,7 @@
"user_impersonation_heading": "Emprunt d'identité",
"user_impersonation_description": "Autorisez notre équipe d'assistance à se connecter temporairement à votre place pour nous aider à résoudre les problèmes que vous pourriez nous signaler.",
"team_impersonation_description": "Autorisez les propriétaires/administrateurs de votre équipe à se connecter temporairement à votre place.",
"cal_signup_description": "Gratuit pour les particuliers. Plans Équipes pour les fonctionnalités collaboratives.",
"make_team_private": "Rendre l'équipe privée",
"make_team_private_description": "Les membres de votre équipe ne pourront pas voir les autres membres de l'équipe si cette option est activée.",
"you_cannot_see_team_members": "Vous ne pouvez pas voir tous les membres d'une équipe privée.",
@ -1303,7 +1307,6 @@
"profile_picture": "Photo de profil",
"upload": "Télécharger",
"add_profile_photo": "Ajouter une photo de profil",
"web3": "Web3",
"token_address": "Adresse du token",
"blockchain": "Blockchain",
"old_password": "Ancien mot de passe",
@ -1345,7 +1348,6 @@
"connect_automation_apps": "Connecter des apps d'automatisation",
"connect_analytics_apps": "Connecter des apps d'analytique",
"connect_other_apps": "Connecter d'autres applications",
"connect_web3_apps": "Connecter des apps Web3",
"connect_messaging_apps": "Connecter des apps de messagerie",
"connect_crm_apps": "Connecter des apps de CRM",
"current_step_of_total": "Étape {{currentStep}} sur {{maxSteps}}",
@ -1528,6 +1530,7 @@
"your_org_disbanded_successfully": "Votre organisation a bien été dissoute",
"error_creating_team": "Erreur lors de la création de l'équipe",
"you": "Vous",
"or_continue_with": "Ou continuez avec",
"resend_email": "Renvoyer le-mail",
"member_already_invited": "Le membre a déjà été invité",
"already_in_use_error": "Nom d'utilisateur déjà utilisé",
@ -1584,6 +1587,7 @@
"enable_apps": "Activer les applications",
"enable_apps_description": "Activer les applications que les utilisateurs peuvent intégrer à {{appName}}",
"purchase_license": "Acheter une licence",
"already_have_account": "J'ai déjà un compte",
"already_have_key": "J'ai déjà une clé :",
"already_have_key_suggestion": "Veuillez copier votre variable d'environnement CALCOM_LICENSE_KEY existante ici.",
"app_is_enabled": "{{appName}} est activé",
@ -2056,7 +2060,9 @@
"include_calendar_event": "Inclure l'événement du calendrier",
"recently_added": "Ajoutées récemment",
"connect_all_calendars": "Connectez vos calendriers",
"connect_all_calendars_description": "{{appName}} relève la disponibilité de tous vos calendriers existants.",
"workflow_automation": "Automatisation de workflows",
"workflow_automation_description": "Personnalisez votre expérience de planification avec les workflows",
"scheduling_for_your_team": "Automatisation de workflows",
"no_members_found": "Aucun membre trouvé",
"event_setup_length_error": "Configuration de l'événement : la durée doit être d'au moins 1 minute.",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} יספק כתובת קישור לפגישת Tandem.",
"cal_provide_video_meeting_url": "{{appName}} יספק כתובת קישור לפגישת וידאו.",
"cal_provide_jitsi_meeting_url": "אנחנו ניצור עבורך כתובת URL לפגישת Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "{{appName}} יספק כתובת קישור לפגישת וידאו web3 ב- Huddle01.",
"cal_provide_huddle01_meeting_url": "{{appName}} יספק כתובת קישור לפגישת וידאו ב- Huddle01.",
"cal_provide_teams_meeting_url": "{{appName}} יספק כתובת קישור לפגישת MS Teams. הערה: חייב להיות חשבון של מקום עבודה או בית ספר",
"require_payment": "דרישת תשלום",
"you_need_to_add_a_name": "יש להוסיף שם",
@ -904,7 +904,6 @@
"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": "הגדר/הגדירח את לוחות השנה כדי לבדוק אם יש התנגשויות על מנת למנוע כפל הזמנות.",
@ -913,7 +912,6 @@
"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": "ניתוח נתונים",
@ -1304,7 +1302,6 @@
"profile_picture": "תמונת פרופיל",
"upload": "העלאה",
"add_profile_photo": "הוספת תמונת פרופיל",
"web3": "Web3",
"token_address": "כתובת הטוקן",
"blockchain": "בלוקצ'יין",
"old_password": "סיסמה ישנה",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "קישור אפליקציות אוטומציה",
"connect_analytics_apps": "קישור אפליקציות ניתוח נתונים",
"connect_other_apps": "חיבור אפליקציות אחרות",
"connect_web3_apps": "חבר אפליקציות web3",
"connect_messaging_apps": "קישור אפליקציות מסרים מידיים",
"connect_crm_apps": "קישור אפליקציות CRM",
"current_step_of_total": "שלב {{currentStep}} מתוך {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} fornirà un URL di riunione Tandem.",
"cal_provide_video_meeting_url": "{{appName}} fornirà un URL di riunione Daily video.",
"cal_provide_jitsi_meeting_url": "{{appName}} fornirà un URL di riunione Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "{{appName}} fornirà un URL di riunione Huddle01 web3 video.",
"cal_provide_huddle01_meeting_url": "{{appName}} fornirà un URL di riunione Huddle01 video.",
"cal_provide_teams_meeting_url": "{{appName}} fornirà un URL per la riunione MS Teams. NOTA: È NECESSARIO POSSEDERE UN ACCOUNT LAVORATIVO O SCOLASTICO",
"require_payment": "Richiedi Pagamento",
"you_need_to_add_a_name": "Indica un nome",
@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Aggiungi un'app di analisi per le tue pagine di prenotazione",
"no_category_apps_description_automation": "Aggiungi un'app di automazione da usare",
"no_category_apps_description_other": "Aggiungi qualsiasi altra app per fare altre attività",
"no_category_apps_description_web3": "Aggiungi un'app Web3 per le tue pagine di prenotazione",
"no_category_apps_description_messaging": "Aggiungi un'app di messaggistica per impostare notifiche e promemoria personalizzati",
"no_category_apps_description_crm": "Aggiungi un'app CRM per tenere traccia delle persone che hai incontrato",
"installed_app_calendar_description": "Imposta uno o più calendari per controllare i conflitti ed evitare doppie prenotazioni.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Tutte le app installate appartenenti ad altre categorie.",
"installed_app_conferencing_description": "Scegli quali app di conferenza utilizzare",
"installed_app_automation_description": "Imposta quali app di automazione usare",
"installed_app_web3_description": "Imposta quali app Web3 usare per le tue pagine di prenotazione",
"installed_app_messaging_description": "Scegli le app di messaggistica da usare per impostare notifiche e promemoria personalizzati",
"installed_app_crm_description": "Scegli quali app CRM utilizzare per tenere traccia delle persone che hai incontrato",
"analytics": "Analisi",
@ -1304,7 +1302,6 @@
"profile_picture": "Immagine del profilo",
"upload": "Carica",
"add_profile_photo": "Aggiungi foto del profilo",
"web3": "Web3",
"token_address": "Indirizzo token",
"blockchain": "Blockchain",
"old_password": "Vecchia password",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Connetti app di automazione",
"connect_analytics_apps": "Connetti app di analisi",
"connect_other_apps": "Connetti altre app",
"connect_web3_apps": "Connetti app Web3",
"connect_messaging_apps": "Connetti app di messaggistica",
"connect_crm_apps": "Connetti app CRM",
"current_step_of_total": "Passo {{currentStep}} di {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} は Tandem ミーティングの URL を提供する。",
"cal_provide_video_meeting_url": "{{appName}} はビデオミーティングの URL を提供する。",
"cal_provide_jitsi_meeting_url": "Cal は Jitsi Meet の URL を提供する。",
"cal_provide_huddle01_meeting_url": "{{appName}} は Huddle01 web3 ビデオミーティングの URL を提供する。",
"cal_provide_huddle01_meeting_url": "{{appName}} は Huddle01 ビデオミーティングの URL を提供する。",
"cal_provide_teams_meeting_url": "{{appName}} は、MS Teams のミーティングの URL を提供する。注: 職場や学校のアカウントが必要です。",
"require_payment": "有料",
"you_need_to_add_a_name": "名前を追加する必要があります",
@ -904,7 +904,6 @@
"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": "ダブルブッキングを防ぐために、カレンダーの重複をチェックするように設定します。",
@ -913,7 +912,6 @@
"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": "分析",
@ -1304,7 +1302,6 @@
"profile_picture": "プロフィール写真",
"upload": "アップロード",
"add_profile_photo": "プロフィール写真を追加",
"web3": "Web3",
"token_address": "トークンアドレス",
"blockchain": "ブロックチェーン",
"old_password": "古いパスワード",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "自動化アプリを接続する",
"connect_analytics_apps": "分析アプリを接続する",
"connect_other_apps": "その他のアプリを接続",
"connect_web3_apps": "Web3 アプリを接続",
"connect_messaging_apps": "メッセージングアプリを接続する",
"connect_crm_apps": "CRM アプリを接続する",
"current_step_of_total": "ステップ {{currentStep}}/{{maxSteps}}",

View File

@ -904,7 +904,6 @@
"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": "중복 예약을 방지하기 위해 충돌을 확인하도록 캘린더를 설정합니다.",
@ -913,7 +912,6 @@
"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": "분석",
@ -1304,7 +1302,6 @@
"profile_picture": "프로필 사진",
"upload": "업로드",
"add_profile_photo": "프로필 사진 추가",
"web3": "Web3",
"token_address": "토큰 주소",
"blockchain": "블록체인",
"old_password": "이전 비밀번호",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "자동화 앱 연결",
"connect_analytics_apps": "분석 앱 연결",
"connect_other_apps": "기타 앱 연결",
"connect_web3_apps": "web3 앱 연결",
"connect_messaging_apps": "메시징 앱 연결",
"connect_crm_apps": "CRM 앱 연결",
"current_step_of_total": "{{maxSteps}} 중 {{currentStep}} 단계",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} zal een Tandem meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_video_meeting_url": "{{appName}} zal een Daily meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_jitsi_meeting_url": "{{appName}} zal een Jitsi Meet meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_huddle01_meeting_url": "{{appName}} zal een Huddle01 web3 meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_huddle01_meeting_url": "{{appName}} zal een Huddle01 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",
@ -904,7 +904,6 @@
"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.",
@ -913,7 +912,6 @@
"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",
@ -1304,7 +1302,6 @@
"profile_picture": "Profielafbeelding",
"upload": "Uploaden",
"add_profile_photo": "Profielfoto toevoegen",
"web3": "Web3",
"token_address": "Tokenadres",
"blockchain": "Blockchain",
"old_password": "Oude wachtwoord",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Koppel automatiseringsapps",
"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}}",

View File

@ -670,7 +670,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} vil angi en URL for Tandem-møtet.",
"cal_provide_video_meeting_url": "{{appName}} vil angi en videomøte-URL.",
"cal_provide_jitsi_meeting_url": "Vi vil generere en Jitsi Meet URL for deg.",
"cal_provide_huddle01_meeting_url": "{{appName}} vil angi en Huddle01 web3 videomøte-URL.",
"cal_provide_huddle01_meeting_url": "{{appName}} vil angi en Huddle01 videomøte-URL.",
"cal_provide_teams_meeting_url": "{{appName}} vil angi en URL for MS Teams møte. MERK: MÅ HA EN ARBEIDS- ELLER SKOLEKONTO",
"require_payment": "Krev Betaling",
"commission_per_transaction": "provisjon per transaksjon",
@ -1112,7 +1112,6 @@
"profile_picture": "Profilbilde",
"upload": "Last opp",
"add_profile_photo": "Legg til profilbilde",
"web3": "Web3",
"token_address": "Token Adresse",
"blockchain": "Blockchain",
"old_password": "Gammelt passord",

View File

@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Dodaj aplikację analityczną do stron rezerwacji",
"no_category_apps_description_automation": "Dodaj aplikację automatyzującą, która ma być używana",
"no_category_apps_description_other": "Dodaj dowolny typ aplikacji, aby uzyskać dostęp do różnych innych funkcji",
"no_category_apps_description_web3": "Dodaj aplikację web3 do stron rezerwacji",
"no_category_apps_description_messaging": "Dodaj aplikację do wysyłania wiadomości, aby skonfigurować własne powiadomienia i przypomnienia",
"no_category_apps_description_crm": "Dodaj aplikację CRM, aby monitorować to, z kim się spotykasz",
"installed_app_calendar_description": "Ustaw kalendarze, aby wykrywać konflikty i unikać podwójnych rezerwacji.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Wszystkie zainstalowane aplikacje z innych kategorii.",
"installed_app_conferencing_description": "Skonfiguruj, z których aplikacji konferencyjnych chcesz korzystać",
"installed_app_automation_description": "Skonfiguruj, które aplikacje automatyzujące mają być używane",
"installed_app_web3_description": "Skonfiguruj aplikacje web3, które mają być używane na stronach rezerwacji",
"installed_app_messaging_description": "Skonfiguruj aplikacje, które będą używane do ustawiania niestandardowych powiadomień i przypomnień",
"installed_app_crm_description": "Skonfiguruj aplikacje CRM, za pomocą których chcesz monitorować to, z kim się spotykasz",
"analytics": "Analityka",
@ -1304,7 +1302,6 @@
"profile_picture": "Zdjęcie profilowe",
"upload": "Prześlij",
"add_profile_photo": "Dodaj zdjęcie profilowe",
"web3": "Web3",
"token_address": "Adres tokena",
"blockchain": "Blockchain",
"old_password": "Stare hasło",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Połącz aplikacje automatyzujące",
"connect_analytics_apps": "Połącz aplikacje analityczne",
"connect_other_apps": "Połącz inne aplikacje",
"connect_web3_apps": "Połącz aplikacje web3",
"connect_messaging_apps": "Podłącz aplikacje do wysyłania wiadomości",
"connect_crm_apps": "Podłącz aplikacje CRM",
"current_step_of_total": "Krok {{currentStep}} z {{maxSteps}}",

View File

@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Adicione um aplicativo de análise às suas páginas de reservas",
"no_category_apps_description_automation": "Adicione um aplicativo de automação para usar",
"no_category_apps_description_other": "Adicione qualquer outro tipo de aplicativo para fazer todos os tipos de coisas",
"no_category_apps_description_web3": "Adicione um aplicativo web3 para suas páginas de reservas",
"no_category_apps_description_messaging": "Adicione um aplicativo de mensagem para definir lembretes e notificações personalizados",
"no_category_apps_description_crm": "Adicione um aplicativo CRM para acompanhar todos os integrantes das suas reuniões",
"installed_app_calendar_description": "Defina o(s) calendário(s) para verificar se há conflitos e evitar reservas duplas.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Todos os seus aplicativos instalados de outras categorias.",
"installed_app_conferencing_description": "Configure quais aplicativos de conferência serão usados",
"installed_app_automation_description": "Configure quais aplicativos de automação serão usados",
"installed_app_web3_description": "Configure quais aplicativos web3 serão usados nas suas páginas de reservas",
"installed_app_messaging_description": "Configure quais aplicativos de mensagem usar para definir lembretes e notificações",
"installed_app_crm_description": "Configure quais aplicativos CRM usar para acompanhar os integrantes das suas reuniões",
"analytics": "Análise",
@ -1304,7 +1302,6 @@
"profile_picture": "Imagem do perfil",
"upload": "Enviar",
"add_profile_photo": "Adicionar foto do perfil",
"web3": "Web3",
"token_address": "Endereço do Token",
"blockchain": "Blockchain",
"old_password": "Senha antiga",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Conecte aplicativos de automação",
"connect_analytics_apps": "Conecte aplicativos de análise",
"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}}",

View File

@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Adicionar uma aplicação de análise às suas páginas de reservas",
"no_category_apps_description_automation": "Adicionar uma aplicação de automatização a utilizar",
"no_category_apps_description_other": "Adicione qualquer outro tipo de aplicações para fazer todos os tipos de coisas",
"no_category_apps_description_web3": "Adicione uma aplicação web3 às suas páginas de reservas",
"no_category_apps_description_messaging": "Adicione uma aplicação de mensagens para configurar notificações e lembretes personalizados",
"no_category_apps_description_crm": "Adicione uma aplicação de CRM para manter um registo das pessoas com quem se reuniu",
"installed_app_calendar_description": "Defina o(s) calendário(s) para verificar se existem conflitos e assim evitar marcações sobrepostas.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Todas as aplicações instaladas de outras categorias.",
"installed_app_conferencing_description": "Configurar as aplicações de conferência a utilizar",
"installed_app_automation_description": "Configurar as aplicações de automatização a utilizar",
"installed_app_web3_description": "Configure as aplicações web3 a utilizar nas suas páginas de reservas",
"installed_app_messaging_description": "Configurar as aplicações de mensagens a utilizar para definir notificações e lembretes personalizados",
"installed_app_crm_description": "Configurar as aplicações de CRM a utilizar para manter um registo das pessoas com quem se reuniu",
"analytics": "Estatísticas",
@ -1304,7 +1302,6 @@
"profile_picture": "Imagem do perfil",
"upload": "Carregar",
"add_profile_photo": "Adicionar imagem de perfil",
"web3": "Web3",
"token_address": "Endereço do Token",
"blockchain": "Blockchain",
"old_password": "Palavra-passe antiga",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Associar aplicações de automatização",
"connect_analytics_apps": "Associar aplicações de estatística",
"connect_other_apps": "Associe outras aplicações",
"connect_web3_apps": "Associe aplicações web3",
"connect_messaging_apps": "Ligar aplicações de mensagens",
"connect_crm_apps": "Ligar aplicações CRM",
"current_step_of_total": "Passo {{currentStep}} de {{maxSteps}}",

View File

@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Adăugați o aplicație de analiză pentru paginile dvs. de rezervări",
"no_category_apps_description_automation": "Adăugați o aplicație de automatizare de utilizat",
"no_category_apps_description_other": "Adăugați orice alt tip de aplicație pentru a întreprinde diverse acțiuni",
"no_category_apps_description_web3": "Adăugați o aplicație Web3 pentru paginile dvs. de rezervări",
"no_category_apps_description_messaging": "Adăugați o aplicație de mesagerie pentru a configura notificări și mementouri personalizate",
"no_category_apps_description_crm": "Adăugați o aplicație CRM pentru a ține evidența persoanelor cu care v-ați întâlnit",
"installed_app_calendar_description": "Pentru a evita rezervările suprapuse, configurează calendarele astfel încât să poată verifica existența conflictelor.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Toate aplicațiile instalate din alte categorii.",
"installed_app_conferencing_description": "Configurați ce aplicații de conferințe vor fi utilizate",
"installed_app_automation_description": "Configurați care aplicații de automatizare vor fi utilizate",
"installed_app_web3_description": "Configurați care aplicații Web3 vor fi utilizate pentru paginile dvs. de rezervări",
"installed_app_messaging_description": "Definiți ce aplicații de mesagerie vor fi utilizate pentru configurarea de notificări și mementouri personalizate",
"installed_app_crm_description": "Configurați ce aplicații CRM vor fi utilizate pentru a ține evidența persoanelor cu care v-ați întâlnit",
"analytics": "Analiză",
@ -1304,7 +1302,6 @@
"profile_picture": "Fotografie de profil",
"upload": "Încărcare",
"add_profile_photo": "Adăugați poză de profil",
"web3": "Web3",
"token_address": "Adresă token",
"blockchain": "Blockchain",
"old_password": "Parola veche",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Conectați aplicații de automatizare",
"connect_analytics_apps": "Conectați aplicații de analiză",
"connect_other_apps": "Conectați alte aplicații",
"connect_web3_apps": "Conectați aplicații Web3",
"connect_messaging_apps": "Conectați aplicații de mesagerie",
"connect_crm_apps": "Conectați aplicații CRM",
"current_step_of_total": "Pasul {{currentStep}} din {{maxSteps}}",

View File

@ -904,7 +904,6 @@
"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": "Настройте проверку календарей на предмет конфликтов для избежания двойного бронирования.",
@ -913,7 +912,6 @@
"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": "Аналитика",
@ -1304,7 +1302,6 @@
"profile_picture": "Фото профиля",
"upload": "Загрузить",
"add_profile_photo": "Добавить фото профиля",
"web3": "Web3",
"token_address": "Адрес токена",
"blockchain": "Блокчейн",
"old_password": "Старый пароль",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Подключить приложения для автоматизации",
"connect_analytics_apps": "Подключить приложения аналитики",
"connect_other_apps": "Подключить другие приложения",
"connect_web3_apps": "Подключить приложения web3",
"connect_messaging_apps": "Подключить мессенджеры",
"connect_crm_apps": "Подключить CRM-приложения",
"current_step_of_total": "Шаг {{currentStep}} из {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} će obezbediti URL Tandem sastanka.",
"cal_provide_video_meeting_url": "{{appName}} će obezbediti Daily video meeting URL.",
"cal_provide_jitsi_meeting_url": "Mi ćemo generisati Jitsi Meet URL za vas.",
"cal_provide_huddle01_meeting_url": "{{appName}} će obezbediti Huddle01 web3 video meeting URL.",
"cal_provide_huddle01_meeting_url": "{{appName}} će obezbediti Huddle01 video meeting URL.",
"cal_provide_teams_meeting_url": "{{appName}} će dostaviti URL adresu MS Teams sastanka. NAPOMENA: NEOPHODAN JE POSLOVNI ILI ŠKOLSKI NALOG",
"require_payment": "Obavezno plaćanje",
"you_need_to_add_a_name": "Potrebno je da dodate ime",
@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Dodajte analitičku aplikaciju za vaše stranice za rezervacije",
"no_category_apps_description_automation": "Dodajte aplikaciju za automatizaciju za korišćenje",
"no_category_apps_description_other": "Dodajte bilo koju vrstu aplikacije da biste uradili svakakve stvari",
"no_category_apps_description_web3": "Dodajte web3 aplikaciju na stranice za rezervacije",
"no_category_apps_description_messaging": "Dodajte aplikaciju za poruke da biste podesili uobičajena obaveštenja i podsetnike",
"no_category_apps_description_crm": "Dodajte aplikaciju za CRM da biste pratili sa kim ste se sreli",
"installed_app_calendar_description": "Podesite kalendar(e) da biste proverili da li postoje konflikti i time sprečili dvostruka zakazivanja.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Sve vaše instalirane aplikacije iz drugih kategorija.",
"installed_app_conferencing_description": "Konfigurišite koje aplikacije ćete koristiti za konferencije",
"installed_app_automation_description": "Konfigurišite koje ćete aplikacije za automatizaciju da koristite",
"installed_app_web3_description": "Konfigurišite koje web3 aplikacije će se koristiti za stranice za rezervacije",
"installed_app_messaging_description": "Konfigurišite koje aplikacije za poruke ćete koristiti da biste podesili uobičajena obaveštenja i podsetnike",
"installed_app_crm_description": "Konfigurišite koje CRM aplikacije ćete koristiti za praćenje sa kim ste se sreli",
"analytics": "Analitika",
@ -1304,7 +1302,6 @@
"profile_picture": "Profilna slika",
"upload": "Otpremi",
"add_profile_photo": "Dodajte profilnu fotografiju",
"web3": "Web3",
"token_address": "Adresa tokena",
"blockchain": "Lanac blokova",
"old_password": "Stara lozinka",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Povežite aplikacije za automatizaciju",
"connect_analytics_apps": "Povežite analitičke aplikacije",
"connect_other_apps": "Povežite druge aplikacije",
"connect_web3_apps": "Povežite web3 aplikacije",
"connect_messaging_apps": "Povežite aplikacije za razmenu poruka",
"connect_crm_apps": "Povežite CRM aplikacije",
"current_step_of_total": "Korak {{currentStep}} od {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} kommer att generera en URL för Tandem-möte.",
"cal_provide_video_meeting_url": "{{appName}} kommer att generera en URL för Daily video-möte.",
"cal_provide_jitsi_meeting_url": "Vi kommer att generera en Jitsi Meet URL för dig.",
"cal_provide_huddle01_meeting_url": "{{appName}} kommer att generera en URL för Huddle01 web3-möte.",
"cal_provide_huddle01_meeting_url": "{{appName}} kommer att generera en URL för Huddle01-möte.",
"cal_provide_teams_meeting_url": "{{appName}} kommer att tillhandahålla en mötes-URL för MS Teams. OBS! MÅSTE HA ETT ARBETS- ELLER SKOLKONTO",
"require_payment": "Begär betalning",
"you_need_to_add_a_name": "Du måste lägga till ett namn",
@ -904,7 +904,6 @@
"no_category_apps_description_analytics": "Lägg till en analysapp för dina bokningssidor",
"no_category_apps_description_automation": "Lägg till en automationsapp att använda",
"no_category_apps_description_other": "Lägg till en annan typ av app för att göra alla möjliga saker",
"no_category_apps_description_web3": "Lägg till en web3-app för dina bokningssidor",
"no_category_apps_description_messaging": "Lägg till en meddelandeapp för att skapa anpassade aviseringar och påminnelser",
"no_category_apps_description_crm": "Lägg till en CRM-app för att hålla reda på vilka du har träffat",
"installed_app_calendar_description": "Ställ in kalendrar att söka efter konflikter för att undvika dubbelbokningar.",
@ -913,7 +912,6 @@
"installed_app_other_description": "Alla dina installerade appar från andra kategorier.",
"installed_app_conferencing_description": "Konfigurera vilka konferensappar som ska användas",
"installed_app_automation_description": "Konfigurera vilka automationsappar som ska användas",
"installed_app_web3_description": "Konfigurera vilka web3-appar som ska användas för dina bokningssidor",
"installed_app_messaging_description": "Konfigurera vilka meddelandeappar som ska användas för att skapa anpassade aviseringar och påminnelser",
"installed_app_crm_description": "Konfigurera vilka CRM-appar som ska användas för att hålla reda på vilka du har träffat",
"analytics": "Analys",
@ -1304,7 +1302,6 @@
"profile_picture": "Profilbild",
"upload": "Ladda upp",
"add_profile_photo": "Lägg till profilfoto",
"web3": "Web3",
"token_address": "Tokenadress",
"blockchain": "Blockkedja",
"old_password": "Gammalt lösenord",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Anslut automationsappar",
"connect_analytics_apps": "Anslut analysappar",
"connect_other_apps": "Anslut andra appar",
"connect_web3_apps": "Anslut web3-appar",
"connect_messaging_apps": "Anslut meddelandeappar",
"connect_crm_apps": "Anslut CRM-appar",
"current_step_of_total": "Steg {{currentStep}} av {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}}, bir Tandem toplantı URL'si sağlayacaktır.",
"cal_provide_video_meeting_url": "{{appName}}, bir görüntülü toplantı URL'si sağlayacaktır.",
"cal_provide_jitsi_meeting_url": "Sizin için bir Jitsi Meet URL'si oluşturacağız.",
"cal_provide_huddle01_meeting_url": "{{appName}}, bir Huddle01 web3 görüntülü toplantı URL'si sağlayacaktır.",
"cal_provide_huddle01_meeting_url": "{{appName}}, bir Huddle01 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": "Ad eklemeniz gerekiyor",
@ -904,7 +904,6 @@
"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.",
@ -913,7 +912,6 @@
"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",
@ -1304,7 +1302,6 @@
"profile_picture": "Profil resmi",
"upload": "Yükle",
"add_profile_photo": "Profil fotoğrafı ekleyin",
"web3": "Web3",
"token_address": "Token Adresi",
"blockchain": "Blok zinciri",
"old_password": "Eski şifre",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Otomasyon uygulamaları bağlayın",
"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",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} надасть URL-адресу наради Tandem.",
"cal_provide_video_meeting_url": "{{appName}} надасть URL-адресу наради Daily.",
"cal_provide_jitsi_meeting_url": "Ми згенеруємо URL-адресу Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "{{appName}} надасть URL-адресу відеонаради Huddle01 web3.",
"cal_provide_huddle01_meeting_url": "{{appName}} надасть URL-адресу відеонаради Huddle01.",
"cal_provide_teams_meeting_url": "{{appName}} надасть URL-адресу наради в MS Teams. ПРИМІТКА: ПОТРІБЕН РОБОЧИЙ АБО НАВЧАЛЬНИЙ ОБЛІКОВИЙ ЗАПИС",
"require_payment": "Вимагати оплату",
"you_need_to_add_a_name": "Потрібно додати ім’я",
@ -904,7 +904,6 @@
"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": "Налаштуйте календарі, щоб перевіряти, чи немає конфліктів у розкладі, і уникати подвійних бронювань.",
@ -913,7 +912,6 @@
"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": "Аналітика",
@ -1304,7 +1302,6 @@
"profile_picture": "Зображення профілю",
"upload": "Передати",
"add_profile_photo": "Додати фото профілю",
"web3": "Web3",
"token_address": "Адреса токена",
"blockchain": "Блокчейн",
"old_password": "Старий пароль",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Підключити додатки для автоматизації",
"connect_analytics_apps": "Підключити аналітичні додатки",
"connect_other_apps": "Підключити інші додатки",
"connect_web3_apps": "Підключити додатки web3",
"connect_messaging_apps": "Підключити застосунки для повідомлень",
"connect_crm_apps": "Підключити застосунки CRM",
"current_step_of_total": "Крок {{currentStep}} із {{maxSteps}}",

View File

@ -801,7 +801,7 @@
"cal_provide_tandem_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp Tandem.",
"cal_provide_video_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp video.",
"cal_provide_jitsi_meeting_url": "Chúng tôi sẽ tạo một URL Jitsi Meet cho bạn.",
"cal_provide_huddle01_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp video Huddle01 web3.",
"cal_provide_huddle01_meeting_url": "{{appName}} sẽ cung cấp URL cuộc họp video Huddle01.",
"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",
@ -904,7 +904,6 @@
"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.",
@ -913,7 +912,6 @@
"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",
@ -1304,7 +1302,6 @@
"profile_picture": "Ảnh hồ sơ",
"upload": "Tải lên",
"add_profile_photo": "Thêm ảnh hồ sơ",
"web3": "Web3",
"token_address": "Địa chỉ token",
"blockchain": "Chuỗi khối",
"old_password": "Mật khẩu cũ",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "Kết nối các ứng dụng tự động hoá",
"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}}",

View File

@ -801,7 +801,7 @@
"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_huddle01_meeting_url": "{{appName}} 将提供 Huddle01 视频会议链接",
"cal_provide_teams_meeting_url": "{{appName}} 将提供 MS Teams 会议 URL。注意: 须拥有工作或学校帐户",
"require_payment": "需要付款",
"you_need_to_add_a_name": "您需要添加名称",
@ -905,7 +905,6 @@
"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": "设置日历以检查冲突,防止重复预约。",
@ -914,7 +913,6 @@
"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": "分析",
@ -1305,7 +1303,6 @@
"profile_picture": "个人资料图片",
"upload": "上传",
"add_profile_photo": "添加个人资料照片",
"web3": "Web3",
"token_address": "代币地址",
"blockchain": "区块链",
"old_password": "旧密码",
@ -1347,7 +1344,6 @@
"connect_automation_apps": "连接自动化应用",
"connect_analytics_apps": "连接分析应用",
"connect_other_apps": "连接其他应用",
"connect_web3_apps": "连接 web3 应用",
"connect_messaging_apps": "连接消息应用",
"connect_crm_apps": "连接 CRM 应用",
"current_step_of_total": "第 {{currentStep}} 步,共 {{maxSteps}} 步",

View File

@ -904,7 +904,6 @@
"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": "設定行事曆來檢查衝突,以避免重複預約。",
@ -913,7 +912,6 @@
"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": "分析",
@ -1304,7 +1302,6 @@
"profile_picture": "個人資料圖片",
"upload": "上傳",
"add_profile_photo": "新增個人資料相片",
"web3": "Web3",
"token_address": "代幣地址",
"blockchain": "區塊鏈",
"old_password": "舊密碼",
@ -1346,7 +1343,6 @@
"connect_automation_apps": "連至自動化應用程式",
"connect_analytics_apps": "連至分析應用程式",
"connect_other_apps": "連接其他應用程式",
"connect_web3_apps": "連接 web3 應用程式",
"connect_messaging_apps": "連接傳訊應用程式",
"connect_crm_apps": "連接 CRM 應用程式",
"current_step_of_total": "第 {{currentStep}} 步,共 {{maxSteps}} 步",

View File

@ -5,6 +5,7 @@ import type z from "zod";
import { ErrorCode } from "@calcom/lib/errorCodes";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { IAbstractPaymentService } from "@calcom/types/PaymentService";
@ -87,7 +88,7 @@ export class PaymentService implements IAbstractPaymentService {
}
return paymentData;
} catch (error) {
log.error("Alby: Payment could not be created", bookingId, JSON.stringify(error));
log.error("Alby: Payment could not be created", bookingId, safeStringify(error));
throw new Error(ErrorCode.PaymentCreationFailure);
}
}

View File

@ -9,6 +9,7 @@ import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
import { getLocation, getRichDescription } from "@calcom/lib/CalEventParser";
import type CalendarService from "@calcom/lib/CalendarService";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type {
Calendar,
@ -106,6 +107,7 @@ export default class GoogleCalendarService implements Calendar {
});
myGoogleAuth.setCredentials(googleCredentials);
} catch (err) {
this.log.error("Error Refreshing Google Token", safeStringify(err));
let message;
if (err instanceof Error) message = err.message;
else message = String(err);
@ -251,7 +253,10 @@ export default class GoogleCalendarService implements Calendar {
iCalUID: event.data.iCalUID,
};
} catch (error) {
console.error("There was an error contacting google calendar service: ", error);
this.log.error(
"There was an error creating event in google calendar: ",
safeStringify({ error, selectedCalendar, credentialId })
);
throw error;
}
}
@ -332,7 +337,10 @@ export default class GoogleCalendarService implements Calendar {
}
return evt?.data;
} catch (error) {
console.error("There was an error contacting google calendar service: ", error);
this.log.error(
"There was an error updating event in google calendar: ",
safeStringify({ error, event, uid })
);
throw error;
}
}
@ -354,6 +362,10 @@ export default class GoogleCalendarService implements Calendar {
});
return event?.data;
} catch (error) {
this.log.error(
"There was an error deleting event from google calendar: ",
safeStringify({ error, event, externalCalendarId })
);
const err = error as GoogleCalError;
/**
* 410 is when an event is already deleted on the Google cal before on cal.com
@ -502,7 +514,10 @@ export default class GoogleCalendarService implements Calendar {
return busyData;
}
} catch (error) {
this.log.error("There was an error contacting google calendar service: ", error);
this.log.error(
"There was an error getting availability from google calendar: ",
safeStringify({ error, selectedCalendars })
);
throw error;
}
}
@ -524,7 +539,7 @@ export default class GoogleCalendarService implements Calendar {
} satisfies IntegrationCalendar)
);
} catch (error) {
this.log.error("There was an error contacting google calendar service: ", error);
this.log.error("There was an error getting calendars: ", safeStringify(error));
throw error;
}
}

View File

@ -6,6 +6,7 @@ import Paypal from "@calcom/app-store/paypal/lib/Paypal";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { ErrorCode } from "@calcom/lib/errorCodes";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { IAbstractPaymentService } from "@calcom/types/PaymentService";
@ -91,7 +92,7 @@ export class PaymentService implements IAbstractPaymentService {
}
return paymentData;
} catch (error) {
log.error("Paypal: Payment could not be created for bookingId", bookingId);
log.error("Paypal: Payment could not be created for bookingId", bookingId, safeStringify(error));
throw new Error(ErrorCode.PaymentCreationFailure);
}
}
@ -170,7 +171,11 @@ export class PaymentService implements IAbstractPaymentService {
}
return paymentData;
} catch (error) {
log.error("Paypal: Payment method could not be collected for bookingId", bookingId);
log.error(
"Paypal: Payment method could not be collected for bookingId",
bookingId,
safeStringify(error)
);
throw new Error("Paypal: Payment method could not be collected");
}
}

View File

@ -7,6 +7,7 @@ import { sendAwaitingPaymentEmail } from "@calcom/emails";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { getErrorFromUnknown } from "@calcom/lib/errors";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { IAbstractPaymentService } from "@calcom/types/PaymentService";
@ -132,8 +133,7 @@ export class PaymentService implements IAbstractPaymentService {
}
return paymentData;
} catch (error) {
console.error(`Payment could not be created for bookingId ${bookingId}`, error);
log.error("Stripe: Payment could not be created", bookingId, JSON.stringify(error));
log.error("Stripe: Payment could not be created", bookingId, safeStringify(error));
throw new Error("payment_not_created_error");
}
}
@ -207,7 +207,7 @@ export class PaymentService implements IAbstractPaymentService {
log.error(
"Stripe: Payment method could not be collected for bookingId",
bookingId,
JSON.stringify(error)
safeStringify(error)
);
throw new Error("Stripe: Payment method could not be collected");
}
@ -286,7 +286,7 @@ export class PaymentService implements IAbstractPaymentService {
return paymentData;
} catch (error) {
log.error("Stripe: Could not charge card for payment", _bookingId, JSON.stringify(error));
log.error("Stripe: Could not charge card for payment", _bookingId, safeStringify(error));
throw new Error(ErrorCode.ChargeCardFailure);
}
}
@ -378,7 +378,7 @@ export class PaymentService implements IAbstractPaymentService {
await this.stripe.paymentIntents.cancel(payment.externalId, { stripeAccount });
return true;
} catch (e) {
log.error("Stripe: Unable to delete Payment in stripe of paymentId", paymentId, JSON.stringify(e));
log.error("Stripe: Unable to delete Payment in stripe of paymentId", paymentId, safeStringify(e));
return false;
}
}

View File

@ -144,7 +144,7 @@ const updateMeeting = async (
if (!updatedMeeting) {
log.error(
"updateMeeting failed",
JSON.stringify({ bookingRef, canCallUpdateMeeting, calEvent, credential })
safeStringify({ bookingRef, canCallUpdateMeeting, calEvent, credential })
);
return {
appName: credential.appId || "",

View File

@ -37,6 +37,7 @@ export default function DisconnectIntegration({
},
async onSettled() {
await utils.viewer.connectedCalendars.invalidate();
await utils.viewer.integrations.invalidate();
},
});

View File

@ -0,0 +1,80 @@
import { z } from "zod";
import {
bookingCreateSchemaLegacyPropsForApi,
bookingCreateBodySchemaForApi,
extendedBookingCreateBody,
} from "@calcom/prisma/zod-utils";
import getBookingResponsesSchema from "./getBookingResponsesSchema";
import type { getEventTypesFromDB } from "./handleNewBooking";
const getBookingDataSchema = (
rescheduleUid: string | undefined,
isNotAnApiCall: boolean,
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>>
) => {
const responsesSchema = getBookingResponsesSchema({
eventType: {
bookingFields: eventType.bookingFields,
},
view: rescheduleUid ? "reschedule" : "booking",
});
const bookingDataSchema = isNotAnApiCall
? extendedBookingCreateBody.merge(
z.object({
responses: responsesSchema,
})
)
: bookingCreateBodySchemaForApi
.merge(
z.object({
responses: responsesSchema.optional(),
})
)
.superRefine((val, ctx) => {
if (val.responses && val.customInputs) {
ctx.addIssue({
code: "custom",
message:
"Don't use both customInputs and responses. `customInputs` is only there for legacy support.",
});
return;
}
const legacyProps = Object.keys(bookingCreateSchemaLegacyPropsForApi.shape);
if (val.responses) {
const unwantedProps: string[] = [];
legacyProps.forEach((legacyProp) => {
if (typeof val[legacyProp as keyof typeof val] !== "undefined") {
console.error(
`Deprecated: Unexpected falsy value for: ${unwantedProps.join(
","
)}. They can't be used with \`responses\`. This will become a 400 error in the future.`
);
}
if (val[legacyProp as keyof typeof val]) {
unwantedProps.push(legacyProp);
}
});
if (unwantedProps.length) {
ctx.addIssue({
code: "custom",
message: `Legacy Props: ${unwantedProps.join(",")}. They can't be used with \`responses\``,
});
return;
}
} else if (val.customInputs) {
const { success } = bookingCreateSchemaLegacyPropsForApi.safeParse(val);
if (!success) {
ctx.addIssue({
code: "custom",
message: `With \`customInputs\` you must specify legacy props ${legacyProps.join(",")}`,
});
}
}
});
return bookingDataSchema;
};
export default getBookingDataSchema;

View File

@ -3,6 +3,7 @@ import { getWebhookPayloadForBooking } from "@calcom/features/bookings/lib/getWe
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import sendPayload from "@calcom/features/webhooks/lib/sendPayload";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
import type { CalendarEvent } from "@calcom/types/Calendar";
@ -65,6 +66,6 @@ export async function handleBookingRequested(args: {
await Promise.all(promises);
} catch (error) {
// Silently fail
log.error(error);
log.error("Error in handleBookingRequested", safeStringify(error));
}
}

View File

@ -10,6 +10,7 @@ import type { EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
import sendPayload from "@calcom/features/webhooks/lib/sendPayload";
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import type { PrismaClient } from "@calcom/prisma";
import { BookingStatus, WebhookTriggerEvents } from "@calcom/prisma/enums";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
@ -65,7 +66,7 @@ export async function handleConfirmation(args: {
message: "Booking failed",
};
log.error(`Booking ${user.username} failed`, JSON.stringify({ error, results }));
log.error(`Booking ${user.username} failed`, safeStringify({ error, results }));
} else {
if (results.length) {
// TODO: Handle created event metadata more elegantly

View File

@ -77,11 +77,9 @@ import type { BookingReference } from "@calcom/prisma/client";
import { BookingStatus, SchedulingType, WebhookTriggerEvents } from "@calcom/prisma/enums";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import {
bookingCreateBodySchemaForApi,
bookingCreateSchemaLegacyPropsForApi,
customInputSchema,
EventTypeMetaDataSchema,
extendedBookingCreateBody,
userMetadata as userMetadataSchema,
} from "@calcom/prisma/zod-utils";
import type { BufferedBusyTime } from "@calcom/types/BufferedBusyTime";
@ -96,7 +94,7 @@ import type { CredentialPayload } from "@calcom/types/Credential";
import type { EventResult, PartialReference } from "@calcom/types/EventManager";
import type { EventTypeInfo } from "../../webhooks/lib/sendPayload";
import getBookingResponsesSchema from "./getBookingResponsesSchema";
import getBookingDataSchema from "./getBookingDataSchema";
const translator = short();
const log = logger.getSubLogger({ prefix: ["[api] book:user"] });
@ -104,6 +102,14 @@ const log = logger.getSubLogger({ prefix: ["[api] book:user"] });
type User = Prisma.UserGetPayload<typeof userSelect>;
type BufferedBusyTimes = BufferedBusyTime[];
type BookingType = Prisma.PromiseReturnType<typeof getOriginalRescheduledBooking>;
type Booking = Prisma.PromiseReturnType<typeof createBooking>;
export type NewBookingEventType =
| Awaited<ReturnType<typeof getDefaultEvent>>
| Awaited<ReturnType<typeof getEventTypesFromDB>>;
// Work with Typescript to require reqBody.end
type ReqBodyWithoutEnd = z.infer<ReturnType<typeof getBookingDataSchema>>;
type ReqBodyWithEnd = ReqBodyWithoutEnd & { end: string };
interface IEventTypePaymentCredentialType {
appId: EventTypeAppsList;
@ -244,7 +250,7 @@ function checkForConflicts(busyTimes: BufferedBusyTimes, time: dayjs.ConfigType,
return false;
}
const getEventTypesFromDB = async (eventTypeId: number) => {
export const getEventTypesFromDB = async (eventTypeId: number) => {
const eventType = await prisma.eventType.findUniqueOrThrow({
where: {
id: eventTypeId,
@ -363,6 +369,53 @@ type IsFixedAwareUser = User & {
organization: { slug: string };
};
const loadUsers = async (
eventType: NewBookingEventType,
dynamicUserList: string[],
reqHeadersHost: string | undefined
) => {
try {
if (!eventType.id) {
if (!Array.isArray(dynamicUserList) || dynamicUserList.length === 0) {
throw new Error("dynamicUserList is not properly defined or empty.");
}
const users = await prisma.user.findMany({
where: {
username: { in: dynamicUserList },
organization: userOrgQuery(reqHeadersHost ? reqHeadersHost.replace(/^https?:\/\//, "") : ""),
},
select: {
...userSelect.select,
credentials: {
select: credentialForCalendarServiceSelect,
},
metadata: true,
},
});
return users;
}
const hosts = eventType.hosts || [];
if (!Array.isArray(hosts)) {
throw new Error("eventType.hosts is not properly defined.");
}
const users = hosts.map(({ user, isFixed }) => ({
...user,
isFixed,
}));
return users.length ? users : eventType.users;
} catch (error) {
if (error instanceof HttpError || error instanceof Prisma.PrismaClientKnownRequestError) {
throw new HttpError({ statusCode: 400, message: error.message });
}
throw new HttpError({ statusCode: 500, message: "Unable to load users" });
}
};
async function ensureAvailableUsers(
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>> & {
users: IsFixedAwareUser[];
@ -506,73 +559,10 @@ async function getBookingData({
isNotAnApiCall: boolean;
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>>;
}) {
const responsesSchema = getBookingResponsesSchema({
eventType: {
bookingFields: eventType.bookingFields,
},
view: req.body.rescheduleUid ? "reschedule" : "booking",
});
const bookingDataSchema = isNotAnApiCall
? extendedBookingCreateBody.merge(
z.object({
responses: responsesSchema,
})
)
: bookingCreateBodySchemaForApi
.merge(
z.object({
responses: responsesSchema.optional(),
})
)
.superRefine((val, ctx) => {
if (val.responses && val.customInputs) {
ctx.addIssue({
code: "custom",
message:
"Don't use both customInputs and responses. `customInputs` is only there for legacy support.",
});
return;
}
const legacyProps = Object.keys(bookingCreateSchemaLegacyPropsForApi.shape);
if (val.responses) {
const unwantedProps: string[] = [];
legacyProps.forEach((legacyProp) => {
if (typeof val[legacyProp as keyof typeof val] !== "undefined") {
console.error(
`Deprecated: Unexpected falsy value for: ${unwantedProps.join(
","
)}. They can't be used with \`responses\`. This will become a 400 error in the future.`
);
}
if (val[legacyProp as keyof typeof val]) {
unwantedProps.push(legacyProp);
}
});
if (unwantedProps.length) {
ctx.addIssue({
code: "custom",
message: `Legacy Props: ${unwantedProps.join(",")}. They can't be used with \`responses\``,
});
return;
}
} else if (val.customInputs) {
const { success } = bookingCreateSchemaLegacyPropsForApi.safeParse(val);
if (!success) {
ctx.addIssue({
code: "custom",
message: `With \`customInputs\` you must specify legacy props ${legacyProps.join(",")}`,
});
}
}
});
const bookingDataSchema = getBookingDataSchema(req.body?.rescheduleUid, isNotAnApiCall, eventType);
const reqBody = await bookingDataSchema.parseAsync(req.body);
// Work with Typescript to require reqBody.end
type ReqBodyWithoutEnd = z.infer<typeof bookingDataSchema>;
type ReqBodyWithEnd = ReqBodyWithoutEnd & { end: string };
const reqBodyWithEnd = (reqBody: ReqBodyWithoutEnd): reqBody is ReqBodyWithEnd => {
// Use the event length to auto-set the event end time.
if (!Object.prototype.hasOwnProperty.call(reqBody, "end")) {
@ -626,6 +616,181 @@ async function getBookingData({
}
}
async function createBooking({
originalRescheduledBooking,
evt,
eventTypeId,
eventTypeSlug,
reqBodyUser,
reqBodyMetadata,
reqBodyRecurringEventId,
uid,
responses,
isConfirmedByDefault,
smsReminderNumber,
organizerUser,
rescheduleReason,
eventType,
bookerEmail,
paymentAppData,
changedOrganizer,
}: {
originalRescheduledBooking: Awaited<ReturnType<typeof getOriginalRescheduledBooking>>;
evt: CalendarEvent;
eventType: NewBookingEventType;
eventTypeId: Awaited<ReturnType<typeof getBookingData>>["eventTypeId"];
eventTypeSlug: Awaited<ReturnType<typeof getBookingData>>["eventTypeSlug"];
reqBodyUser: ReqBodyWithEnd["user"];
reqBodyMetadata: ReqBodyWithEnd["metadata"];
reqBodyRecurringEventId: ReqBodyWithEnd["recurringEventId"];
uid: short.SUUID;
responses: ReqBodyWithEnd["responses"] | null;
isConfirmedByDefault: ReturnType<typeof getRequiresConfirmationFlags>["isConfirmedByDefault"];
smsReminderNumber: Awaited<ReturnType<typeof getBookingData>>["smsReminderNumber"];
organizerUser: Awaited<ReturnType<typeof loadUsers>>[number] & {
isFixed?: boolean;
metadata?: Prisma.JsonValue;
};
rescheduleReason: Awaited<ReturnType<typeof getBookingData>>["rescheduleReason"];
bookerEmail: Awaited<ReturnType<typeof getBookingData>>["email"];
paymentAppData: ReturnType<typeof getPaymentAppData>;
changedOrganizer: boolean;
}) {
if (originalRescheduledBooking) {
evt.title = originalRescheduledBooking?.title || evt.title;
evt.description = originalRescheduledBooking?.description || evt.description;
evt.location = originalRescheduledBooking?.location || evt.location;
evt.location = changedOrganizer ? evt.location : originalRescheduledBooking?.location || evt.location;
}
const eventTypeRel = !eventTypeId
? {}
: {
connect: {
id: eventTypeId,
},
};
const dynamicEventSlugRef = !eventTypeId ? eventTypeSlug : null;
const dynamicGroupSlugRef = !eventTypeId ? (reqBodyUser as string).toLowerCase() : null;
const attendeesData = evt.attendees.map((attendee) => {
//if attendee is team member, it should fetch their locale not booker's locale
//perhaps make email fetch request to see if his locale is stored, else
return {
name: attendee.name,
email: attendee.email,
timeZone: attendee.timeZone,
locale: attendee.language.locale,
};
});
if (evt.team?.members) {
attendeesData.push(
...evt.team.members.map((member) => ({
email: member.email,
name: member.name,
timeZone: member.timeZone,
locale: member.language.locale,
}))
);
}
const newBookingData: Prisma.BookingCreateInput = {
uid,
responses: responses === null ? Prisma.JsonNull : responses,
title: evt.title,
startTime: dayjs.utc(evt.startTime).toDate(),
endTime: dayjs.utc(evt.endTime).toDate(),
description: evt.additionalNotes,
customInputs: isPrismaObjOrUndefined(evt.customInputs),
status: isConfirmedByDefault ? BookingStatus.ACCEPTED : BookingStatus.PENDING,
location: evt.location,
eventType: eventTypeRel,
smsReminderNumber,
metadata: reqBodyMetadata,
attendees: {
createMany: {
data: attendeesData,
},
},
dynamicEventSlugRef,
dynamicGroupSlugRef,
user: {
connect: {
id: organizerUser.id,
},
},
destinationCalendar:
evt.destinationCalendar && evt.destinationCalendar.length > 0
? {
connect: { id: evt.destinationCalendar[0].id },
}
: undefined,
};
if (reqBodyRecurringEventId) {
newBookingData.recurringEventId = reqBodyRecurringEventId;
}
if (originalRescheduledBooking) {
newBookingData.metadata = {
...(typeof originalRescheduledBooking.metadata === "object" && originalRescheduledBooking.metadata),
};
newBookingData["paid"] = originalRescheduledBooking.paid;
newBookingData["fromReschedule"] = originalRescheduledBooking.uid;
if (originalRescheduledBooking.uid) {
newBookingData.cancellationReason = rescheduleReason;
}
if (newBookingData.attendees?.createMany?.data) {
// Reschedule logic with booking with seats
if (eventType?.seatsPerTimeSlot && bookerEmail) {
newBookingData.attendees.createMany.data = attendeesData.filter(
(attendee) => attendee.email === bookerEmail
);
}
}
if (originalRescheduledBooking.recurringEventId) {
newBookingData.recurringEventId = originalRescheduledBooking.recurringEventId;
}
}
const createBookingObj = {
include: {
user: {
select: { email: true, name: true, timeZone: true, username: true },
},
attendees: true,
payment: true,
references: true,
},
data: newBookingData,
};
if (originalRescheduledBooking?.paid && originalRescheduledBooking?.payment) {
const bookingPayment = originalRescheduledBooking?.payment?.find((payment) => payment.success);
if (bookingPayment) {
createBookingObj.data.payment = {
connect: { id: bookingPayment.id },
};
}
}
if (typeof paymentAppData.price === "number" && paymentAppData.price > 0) {
/* Validate if there is any payment app credential for this user */
await prisma.credential.findFirstOrThrow({
where: {
appId: paymentAppData.appId,
...(paymentAppData.credentialId ? { id: paymentAppData.credentialId } : { userId: organizerUser.id }),
},
select: {
id: true,
},
});
}
return prisma.booking.create(createBookingObj);
}
function getCustomInputsResponses(
reqBody: {
responses?: Record<string, object>;
@ -781,54 +946,11 @@ async function handler(
throw new HttpError({ statusCode: 400, message: error.message });
}
const loadUsers = async () => {
try {
if (!eventTypeId) {
if (!Array.isArray(dynamicUserList) || dynamicUserList.length === 0) {
throw new Error("dynamicUserList is not properly defined or empty.");
}
const users = await prisma.user.findMany({
where: {
username: { in: dynamicUserList },
organization: userOrgQuery(req.headers.host ? req.headers.host.replace(/^https?:\/\//, "") : ""),
},
select: {
...userSelect.select,
credentials: {
select: credentialForCalendarServiceSelect,
},
metadata: true,
},
});
return users;
} else {
const hosts = eventType.hosts || [];
if (!Array.isArray(hosts)) {
throw new Error("eventType.hosts is not properly defined.");
}
const users = hosts.map(({ user, isFixed }) => ({
...user,
isFixed,
}));
return users.length ? users : eventType.users;
}
} catch (error) {
if (error instanceof HttpError || error instanceof Prisma.PrismaClientKnownRequestError) {
throw new HttpError({ statusCode: 400, message: error.message });
}
throw new HttpError({ statusCode: 500, message: "Unable to load users" });
}
};
// loadUsers allows type inferring
let users: (Awaited<ReturnType<typeof loadUsers>>[number] & {
isFixed?: boolean;
metadata?: Prisma.JsonValue;
})[] = await loadUsers();
})[] = await loadUsers(eventType, dynamicUserList, req.headers.host);
const isDynamicAllowed = !users.some((user) => !user.allowDynamicBooking);
if (!isDynamicAllowed && !eventTypeId) {
@ -1923,147 +2045,9 @@ async function handler(
eventType.schedulingType === SchedulingType.ROUND_ROBIN &&
originalRescheduledBooking.userId !== evt.organizer.id;
async function createBooking() {
if (originalRescheduledBooking) {
evt.title = originalRescheduledBooking?.title || evt.title;
evt.description = originalRescheduledBooking?.description || evt.description;
evt.location = changedOrganizer ? evt.location : originalRescheduledBooking?.location || evt.location;
}
const eventTypeRel = !eventTypeId
? {}
: {
connect: {
id: eventTypeId,
},
};
const dynamicEventSlugRef = !eventTypeId ? eventTypeSlug : null;
const dynamicGroupSlugRef = !eventTypeId ? (reqBody.user as string).toLowerCase() : null;
const attendeesData = evt.attendees.map((attendee) => {
//if attendee is team member, it should fetch their locale not booker's locale
//perhaps make email fetch request to see if his locale is stored, else
return {
name: attendee.name,
email: attendee.email,
timeZone: attendee.timeZone,
locale: attendee.language.locale,
};
});
if (evt.team?.members) {
attendeesData.push(
...evt.team.members.map((member) => ({
email: member.email,
name: member.name,
timeZone: member.timeZone,
locale: member.language.locale,
}))
);
}
const newBookingData: Prisma.BookingCreateInput = {
uid,
responses: responses === null ? Prisma.JsonNull : responses,
title: evt.title,
startTime: dayjs.utc(evt.startTime).toDate(),
endTime: dayjs.utc(evt.endTime).toDate(),
description: evt.additionalNotes,
customInputs: isPrismaObjOrUndefined(evt.customInputs),
status: isConfirmedByDefault ? BookingStatus.ACCEPTED : BookingStatus.PENDING,
location: evt.location,
eventType: eventTypeRel,
smsReminderNumber,
metadata: reqBody.metadata,
attendees: {
createMany: {
data: attendeesData,
},
},
dynamicEventSlugRef,
dynamicGroupSlugRef,
user: {
connect: {
id: organizerUser.id,
},
},
destinationCalendar:
evt.destinationCalendar && evt.destinationCalendar.length > 0
? {
connect: { id: evt.destinationCalendar[0].id },
}
: undefined,
};
if (reqBody.recurringEventId) {
newBookingData.recurringEventId = reqBody.recurringEventId;
}
if (originalRescheduledBooking) {
newBookingData.metadata = {
...(typeof originalRescheduledBooking.metadata === "object" && originalRescheduledBooking.metadata),
};
newBookingData["paid"] = originalRescheduledBooking.paid;
newBookingData["fromReschedule"] = originalRescheduledBooking.uid;
if (originalRescheduledBooking.uid) {
newBookingData.cancellationReason = rescheduleReason;
}
if (newBookingData.attendees?.createMany?.data) {
// Reschedule logic with booking with seats
if (eventType?.seatsPerTimeSlot && bookerEmail) {
newBookingData.attendees.createMany.data = attendeesData.filter(
(attendee) => attendee.email === bookerEmail
);
}
}
if (originalRescheduledBooking.recurringEventId) {
newBookingData.recurringEventId = originalRescheduledBooking.recurringEventId;
}
}
const createBookingObj = {
include: {
user: {
select: { email: true, name: true, timeZone: true, username: true },
},
attendees: true,
payment: true,
references: true,
},
data: newBookingData,
};
if (originalRescheduledBooking?.paid && originalRescheduledBooking?.payment) {
const bookingPayment = originalRescheduledBooking?.payment?.find((payment) => payment.success);
if (bookingPayment) {
createBookingObj.data.payment = {
connect: { id: bookingPayment.id },
};
}
}
if (typeof paymentAppData.price === "number" && paymentAppData.price > 0) {
/* Validate if there is any payment app credential for this user */
await prisma.credential.findFirstOrThrow({
where: {
appId: paymentAppData.appId,
...(paymentAppData.credentialId
? { id: paymentAppData.credentialId }
: { userId: organizerUser.id }),
},
select: {
id: true,
},
});
}
return prisma.booking.create(createBookingObj);
}
let results: EventResult<AdditionalInformation & { url?: string; iCalUID?: string }>[] = [];
let referencesToCreate: PartialReference[] = [];
type Booking = Prisma.PromiseReturnType<typeof createBooking>;
let booking: (Booking & { appsStatus?: AppsStatus[] }) | null = null;
loggerWithEventDetails.debug(
"Going to create booking in DB now",
@ -2077,7 +2061,25 @@ async function handler(
);
try {
booking = await createBooking();
booking = await createBooking({
originalRescheduledBooking,
evt,
eventTypeId,
eventTypeSlug,
reqBodyUser: reqBody.user,
reqBodyMetadata: reqBody.metadata,
reqBodyRecurringEventId: reqBody.recurringEventId,
uid,
responses,
isConfirmedByDefault,
smsReminderNumber,
organizerUser,
rescheduleReason,
eventType,
bookerEmail,
paymentAppData,
changedOrganizer,
});
// @NOTE: Add specific try catch for all subsequent async calls to avoid error
// Sync Services

View File

@ -67,7 +67,7 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => {
},
onError() {
setCheckedInternal(false);
showToast(`Something went wrong when toggling "${title}""`, "error");
showToast(`Something went wrong when toggling "${title}"`, "error");
},
}
);
@ -77,9 +77,10 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => {
<Switch
id={externalId}
checked={checkedInternal}
onCheckedChange={(isOn: boolean) => {
disabled={mutation.isLoading}
onCheckedChange={async (isOn: boolean) => {
setCheckedInternal(isOn);
mutation.mutate({ isOn });
await mutation.mutate({ isOn });
}}
/>
</div>

View File

@ -14,6 +14,7 @@ import { HttpError as HttpCode } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
import { getBooking } from "@calcom/lib/payment/getBooking";
import { handlePaymentSuccess } from "@calcom/lib/payment/handlePaymentSuccess";
import { safeStringify } from "@calcom/lib/safeStringify";
import { prisma } from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/enums";
@ -38,7 +39,7 @@ export async function handleStripePaymentSuccess(event: Stripe.Event) {
});
if (!payment?.bookingId) {
log.error(JSON.stringify(paymentIntent), JSON.stringify(payment));
log.error("Stripe: Payment Not Found", safeStringify(paymentIntent), safeStringify(payment));
throw new HttpCode({ statusCode: 204, message: "Payment not found" });
}
if (!payment?.bookingId) throw new HttpCode({ statusCode: 204, message: "Payment not found" });

View File

@ -44,7 +44,7 @@ export function UpgradeTip({
<picture className="absolute min-h-[295px] w-full rounded-lg object-cover">
<source srcSet={`${background}-dark.jpg`} media="(prefers-color-scheme: dark)" />
<img
className="absolute min-h-[295px] w-full rounded-lg object-cover object-left md:object-center"
className="absolute min-h-[295px] w-full rounded-lg object-cover object-left md:object-center select-none"
src={`${background}.jpg`}
loading="lazy"
alt={title}

View File

@ -4,6 +4,7 @@ import { v4 } from "uuid";
import { getHumanReadableLocationValue } from "@calcom/core/location";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server";
import prisma from "@calcom/prisma";
import type { ApiKey } from "@calcom/prisma/client";
@ -75,7 +76,10 @@ export async function addSubscription({
const userId = appApiKey ? appApiKey.userId : account && !account.isTeam ? account.id : null;
const teamId = appApiKey ? appApiKey.teamId : account && account.isTeam ? account.id : null;
log.error(`Error creating subscription for ${teamId ? `team ${teamId}` : `user ${userId}`}.`);
log.error(
`Error creating subscription for ${teamId ? `team ${teamId}` : `user ${userId}`}.`,
safeStringify(error)
);
}
}
@ -157,7 +161,8 @@ export async function deleteSubscription({
log.error(
`Error deleting subscription for user ${
teamId ? `team ${teamId}` : `userId ${userId}`
}, webhookId ${webhookId}`
}, webhookId ${webhookId}`,
safeStringify(err)
);
}
}
@ -260,7 +265,10 @@ export async function listBookings(
const userId = appApiKey ? appApiKey.userId : account && !account.isTeam ? account.id : null;
const teamId = appApiKey ? appApiKey.teamId : account && account.isTeam ? account.id : null;
log.error(`Error retrieving list of bookings for ${teamId ? `team ${teamId}` : `user ${userId}`}.`);
log.error(
`Error retrieving list of bookings for ${teamId ? `team ${teamId}` : `user ${userId}`}.`,
safeStringify(err)
);
}
}

View File

@ -32,7 +32,7 @@ export function deriveAppDictKeyFromType(appType: string, dict: Record<string, u
return appType;
// const categories = ["video", "other", "calendar", "web3", "payment", "messaging"];
// const categories = ["video", "other", "calendar", "payment", "messaging"];
// // Instead of doing a blind split at _ and using the first part, apply this hack only on strings that match legacy type.
// // Transform zoomvideo to zoom

View File

@ -1,6 +1,7 @@
import { Prisma } from "@prisma/client";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
const log = logger.getSubLogger({ prefix: [`[[redactError]`] });
@ -19,7 +20,7 @@ export const redactError = <T extends Error | unknown>(error: T) => {
}
log.debug("Type of Error: ", error.constructor);
if (shouldRedact(error)) {
log.error("Error: ", JSON.stringify(error));
log.error("Error: ", safeStringify(error));
return new Error("An error occured while querying the database.");
}
return error;

View File

@ -217,46 +217,49 @@ export async function createNewUsersConnectToOrgIfExists({
autoAcceptEmailDomain?: string;
connectionInfoMap: Record<string, ReturnType<typeof getOrgConnectionInfo>>;
}) {
await prisma.$transaction(async (tx) => {
for (let index = 0; index < usernamesOrEmails.length; index++) {
const usernameOrEmail = usernamesOrEmails[index];
const { orgId, autoAccept } = connectionInfoMap[usernameOrEmail];
const [emailUser, emailDomain] = usernameOrEmail.split("@");
const username =
emailDomain === autoAcceptEmailDomain
? slugify(emailUser)
: slugify(`${emailUser}-${emailDomain.split(".")[0]}`);
await prisma.$transaction(
async (tx) => {
for (let index = 0; index < usernamesOrEmails.length; index++) {
const usernameOrEmail = usernamesOrEmails[index];
const { orgId, autoAccept } = connectionInfoMap[usernameOrEmail];
const [emailUser, emailDomain] = usernameOrEmail.split("@");
const username =
emailDomain === autoAcceptEmailDomain
? slugify(emailUser)
: slugify(`${emailUser}-${emailDomain.split(".")[0]}`);
const createdUser = await tx.user.create({
data: {
username,
email: usernameOrEmail,
verified: true,
invitedTo: input.teamId,
organizationId: orgId || null, // If the user is invited to a child team, they are automatically added to the parent org
teams: {
create: {
teamId: input.teamId,
role: input.role as MembershipRole,
accepted: autoAccept, // If the user is invited to a child team, they are automatically accepted
const createdUser = await tx.user.create({
data: {
username,
email: usernameOrEmail,
verified: true,
invitedTo: input.teamId,
organizationId: orgId || null, // If the user is invited to a child team, they are automatically added to the parent org
teams: {
create: {
teamId: input.teamId,
role: input.role as MembershipRole,
accepted: autoAccept, // If the user is invited to a child team, they are automatically accepted
},
},
},
},
});
// We also need to create the membership in the parent org if it exists
if (parentId) {
await tx.membership.create({
data: {
teamId: parentId,
userId: createdUser.id,
role: input.role as MembershipRole,
accepted: autoAccept,
},
});
// We also need to create the membership in the parent org if it exists
if (parentId) {
await tx.membership.create({
data: {
teamId: parentId,
userId: createdUser.id,
role: input.role as MembershipRole,
accepted: autoAccept,
},
});
}
}
}
});
},
{ timeout: 10000 }
);
}
export async function createProvisionalMemberships({

View File

@ -63,7 +63,6 @@ export interface App {
| `${string}_messaging`
| `${string}_payment`
| `${string}_video`
| `${string}_web3`
| `${string}_other`
| `${string}_automation`
| `${string}_analytics`
@ -80,15 +79,7 @@ export interface App {
/** A brief description, usually found in the app's package.json */
description: string;
/** TODO determine if we should use this instead of category */
variant:
| "calendar"
| "payment"
| "conferencing"
| "video"
| "other"
| "other_calendar"
| "web3"
| "automation";
variant: "calendar" | "payment" | "conferencing" | "video" | "other" | "other_calendar" | "automation";
/** The slug for the app store public page inside `/apps/[slug] */
slug: string;

1764
yarn.lock

File diff suppressed because it is too large Load Diff