Compare commits
+8
-6
@@ -159,13 +159,17 @@ SENDGRID_EMAIL=
|
||||
NEXT_PUBLIC_SENDGRID_SENDER_NAME=
|
||||
|
||||
# Sentry
|
||||
SENTRY_ORG=
|
||||
SENTRY_PROJECT=
|
||||
SENTRY_AUTH_TOKEN=
|
||||
# Used for capturing exceptions and logging messages
|
||||
NEXT_PUBLIC_SENTRY_DSN=
|
||||
SENTRY_DEBUG=
|
||||
SENTRY_DISABLE_CLIENT_SOURCE_MAPS=
|
||||
SENTRY_DISABLE_SERVER_SOURCE_MAPS=
|
||||
SENTRY_MAX_SPANS=
|
||||
SENTRY_SAMPLE_RATE=
|
||||
SENTRY_TRACES_SAMPLE_RATE=
|
||||
SENTRY_REPLAYS_SESSION_SAMPLE_RATE=
|
||||
SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=
|
||||
|
||||
# Formbricks Experience Management Integration
|
||||
NEXT_PUBLIC_FORMBRICKS_HOST_URL=https://app.formbricks.com
|
||||
@@ -198,6 +202,7 @@ NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE=
|
||||
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN=0
|
||||
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE=
|
||||
STRIPE_TEAM_MONTHLY_PRICE_ID=
|
||||
NEXT_PUBLIC_STRIPE_CREDITS_PRICE_ID=
|
||||
STRIPE_TEAM_PRODUCT_ID=
|
||||
# It is a price ID in the product with id STRIPE_ORG_PRODUCT_ID
|
||||
STRIPE_ORG_MONTHLY_PRICE_ID=
|
||||
@@ -363,9 +368,6 @@ E2E_TEST_OIDC_USER_PASSWORD=
|
||||
|
||||
# ***********************************************************************************************************
|
||||
|
||||
# disable setry server source maps
|
||||
SENTRY_DISABLE_SERVER_WEBPACK_PLUGIN=1
|
||||
|
||||
# api v2
|
||||
NEXT_PUBLIC_API_V2_URL="http://localhost:5555/api/v2"
|
||||
|
||||
@@ -425,7 +427,7 @@ DIRECTORY_IDS_TO_LOG=
|
||||
# Read more about it in the README.md
|
||||
NEXT_PUBLIC_SINGLE_ORG_SLUG=
|
||||
|
||||
AKISMET_API_KEY=
|
||||
IFFY_API_KEY=
|
||||
|
||||
## Env variables related to avoiding booking failures
|
||||
# Request for checking reservation would be attempted to send every these seconds if the request is stale at that time
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/**/package.json @calcom/Foundation
|
||||
/apps/api/**/* @calcom/Platform @calcom/Foundation
|
||||
/apps/ui-playground/**/* @calcom/Consumer @calcom/Foundation
|
||||
/apps/web/components/**/* @calcom/Consumer @calcom/Foundation
|
||||
/apps/web/modules/**/* @calcom/Consumer @calcom/Foundation
|
||||
/apps/web/**/layout.tsx @calcom/Consumer @calcom/Foundation
|
||||
/apps/web/lib/**/* @calcom/Foundation
|
||||
/apps/web/middleware.ts @calcom/Foundation
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Cron - checkSmsPrices
|
||||
|
||||
on:
|
||||
# "Scheduled workflows run on the latest commit on the default or base branch."
|
||||
# — https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#schedule
|
||||
schedule:
|
||||
# Runs “every minute” (see https://crontab.guru)
|
||||
- cron: "* * * * *"
|
||||
jobs:
|
||||
cron-checkSmsPrices:
|
||||
env:
|
||||
APP_URL: ${{ secrets.APP_URL }}
|
||||
CRON_API_KEY: ${{ secrets.CRON_API_KEY }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: cURL request
|
||||
if: ${{ env.APP_URL && env.CRON_API_KEY }}
|
||||
run: |
|
||||
curl ${{ secrets.APP_URL }}/api/cron/checkSmsPrices \
|
||||
-X POST \
|
||||
-H 'content-type: application/json' \
|
||||
-H 'authorization: ${{ secrets.CRON_API_KEY }}' \
|
||||
--fail
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
undecided:
|
||||
- "@calcom/prisma"
|
||||
Vendored
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
undecided:
|
||||
- "@calcom/prisma"
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
undecided:
|
||||
- "@calcom/prisma"
|
||||
@@ -30,7 +30,7 @@
|
||||
"@calcom/lib": "*",
|
||||
"@calcom/prisma": "*",
|
||||
"@calcom/trpc": "*",
|
||||
"@sentry/nextjs": "^8.8.0",
|
||||
"@sentry/nextjs": "^9.15.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"memory-cache": "^0.2.0",
|
||||
"next": "^13.5.9",
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export {};
|
||||
@@ -38,7 +38,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.196",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.197",
|
||||
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
|
||||
@@ -182,7 +182,7 @@ export class BookingsController_2024_08_13 {
|
||||
): Promise<GetBookingsOutput_2024_08_13> {
|
||||
const profile = this.usersService.getUserMainProfile(user);
|
||||
|
||||
const bookings = await this.bookingsService.getBookings(queryParams, {
|
||||
const { bookings, pagination } = await this.bookingsService.getBookings(queryParams, {
|
||||
email: user.email,
|
||||
id: user.id,
|
||||
orgId: profile?.organizationId,
|
||||
@@ -191,6 +191,7 @@ export class BookingsController_2024_08_13 {
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: bookings,
|
||||
pagination,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { UsersModule } from "@/modules/users/users.module";
|
||||
import { INestApplication } from "@nestjs/common";
|
||||
import { NestExpressApplication } from "@nestjs/platform-express";
|
||||
import { Test } from "@nestjs/testing";
|
||||
import { EventType, User } from "@prisma/client";
|
||||
import { EventType, User, Workflow } from "@prisma/client";
|
||||
import { advanceTo, clear } from "jest-date-mock";
|
||||
import * as request from "supertest";
|
||||
import { BookingsRepositoryFixture } from "test/fixtures/repository/bookings.repository.fixture";
|
||||
@@ -22,6 +22,8 @@ import { EventTypesRepositoryFixture } from "test/fixtures/repository/event-type
|
||||
import { OAuthClientRepositoryFixture } from "test/fixtures/repository/oauth-client.repository.fixture";
|
||||
import { TeamRepositoryFixture } from "test/fixtures/repository/team.repository.fixture";
|
||||
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
|
||||
import { WorkflowReminderRepositoryFixture } from "test/fixtures/repository/workflow-reminder.repository.fixture";
|
||||
import { WorkflowRepositoryFixture } from "test/fixtures/repository/workflow.repository.fixture";
|
||||
import { randomString } from "test/utils/randomString";
|
||||
import { withApiAuth } from "test/utils/withApiAuth";
|
||||
|
||||
@@ -32,6 +34,7 @@ import {
|
||||
VERSION_2024_08_13,
|
||||
X_CAL_CLIENT_ID,
|
||||
} from "@calcom/platform-constants";
|
||||
import { AttendeeScheduledEmail, OrganizerScheduledEmail } from "@calcom/platform-libraries/emails";
|
||||
import {
|
||||
CreateEventTypeInput_2024_06_14,
|
||||
FAILED_EVENT_TYPE_IDENTIFICATION_ERROR_MESSAGE,
|
||||
@@ -60,6 +63,8 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
let schedulesService: SchedulesService_2024_04_15;
|
||||
let eventTypesRepositoryFixture: EventTypesRepositoryFixture;
|
||||
let oauthClientRepositoryFixture: OAuthClientRepositoryFixture;
|
||||
let workflowReminderRepositoryFixture: WorkflowReminderRepositoryFixture;
|
||||
let workflowRepositoryFixture: WorkflowRepositoryFixture;
|
||||
let oAuthClient: PlatformOAuthClient;
|
||||
let teamRepositoryFixture: TeamRepositoryFixture;
|
||||
|
||||
@@ -68,6 +73,8 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
|
||||
let eventTypeId: number;
|
||||
let eventType: EventType;
|
||||
let eventTypeWithAttendeeSmsReminder: EventType;
|
||||
let workflow: Workflow;
|
||||
const eventTypeSlug = `user-bookings-event-type-${randomString()}`;
|
||||
let recurringEventTypeId: number;
|
||||
const recurringEventTypeSlug = `user-bookings-event-type-${randomString()}`;
|
||||
@@ -97,6 +104,8 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
oauthClientRepositoryFixture = new OAuthClientRepositoryFixture(moduleRef);
|
||||
teamRepositoryFixture = new TeamRepositoryFixture(moduleRef);
|
||||
schedulesService = moduleRef.get<SchedulesService_2024_04_15>(SchedulesService_2024_04_15);
|
||||
workflowReminderRepositoryFixture = new WorkflowReminderRepositoryFixture(moduleRef);
|
||||
workflowRepositoryFixture = new WorkflowRepositoryFixture(moduleRef);
|
||||
|
||||
organization = await teamRepositoryFixture.create({
|
||||
name: `user-bookings-organization-${randomString()}`,
|
||||
@@ -177,6 +186,85 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
rating: 10,
|
||||
});
|
||||
|
||||
workflow = await workflowRepositoryFixture.create({
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
trigger: "BEFORE_EVENT",
|
||||
time: 24,
|
||||
timeUnit: "HOUR",
|
||||
position: 0,
|
||||
isActiveOnAll: false,
|
||||
name: "Attendee SMS Reminder",
|
||||
steps: {
|
||||
create: {
|
||||
stepNumber: 1,
|
||||
action: "SMS_ATTENDEE",
|
||||
sendTo: null,
|
||||
reminderBody:
|
||||
"Hi {ATTENDEE}, this is a reminder that your meeting ({EVENT_NAME}) with {ORGANIZER} is on {EVENT_DATE_YYYY MMM D} at {EVENT_TIME_h:mma} {TIMEZONE}.",
|
||||
emailSubject: "Reminder: {EVENT_NAME} - {EVENT_DATE_ddd, MMM D, YYYY h:mma}",
|
||||
template: "REMINDER",
|
||||
numberRequired: true,
|
||||
sender: "Cal",
|
||||
numberVerificationPending: false,
|
||||
includeCalendarEvent: false,
|
||||
verifiedAt: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
eventTypeWithAttendeeSmsReminder = await eventTypesRepositoryFixture.create(
|
||||
{
|
||||
title: "event with attendee sms reminder",
|
||||
slug: "event-with-attendee-sms-reminder",
|
||||
length: 15,
|
||||
bookingFields: [
|
||||
{
|
||||
name: "smsReminderNumber",
|
||||
type: "phone",
|
||||
sources: [
|
||||
{
|
||||
id: String(workflow.id),
|
||||
type: "workflow",
|
||||
label: "Workflow",
|
||||
editUrl: `/workflows/${workflow.id}`,
|
||||
fieldRequired: true,
|
||||
},
|
||||
],
|
||||
editable: "system",
|
||||
required: true,
|
||||
defaultLabel: "number_text_notifications",
|
||||
defaultPlaceholder: "enter_phone_number",
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
disableStandardEmails: {
|
||||
all: {
|
||||
attendee: true,
|
||||
host: true,
|
||||
},
|
||||
confirmation: {
|
||||
host: true,
|
||||
attendee: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
workflows: {
|
||||
create: {
|
||||
workflow: {
|
||||
connect: {
|
||||
id: workflow.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
user.id
|
||||
);
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
bootstrap(app as NestExpressApplication);
|
||||
|
||||
@@ -1668,7 +1756,6 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
|
||||
describe("book by username and event type slug", () => {
|
||||
it("should not create a booking by if neither event type id nor username and event type slug provided", async () => {
|
||||
const googleMeetUrl = "https://meet.google.com/abc-def-ghi";
|
||||
const body = {
|
||||
start: new Date(Date.UTC(2036, 0, 8, 15, 0, 0)).toISOString(),
|
||||
attendee: {
|
||||
@@ -1677,7 +1764,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
timeZone: "Europe/Rome",
|
||||
language: "it",
|
||||
},
|
||||
location: googleMeetUrl,
|
||||
location: "https://meet.google.com/abc-def-ghi",
|
||||
bookingFieldsResponses: {
|
||||
customField: "customValue",
|
||||
},
|
||||
@@ -2227,6 +2314,91 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("create booking with attendee sms reminder", () => {
|
||||
it("should not be able create a booking if attendee sms reminder is missing", async () => {
|
||||
const body: CreateBookingInput_2024_08_13 = {
|
||||
start: new Date(Date.UTC(2030, 0, 8, 15, 0, 0)).toISOString(),
|
||||
eventTypeId: eventTypeWithAttendeeSmsReminder.id,
|
||||
attendee: {
|
||||
name: "Mr Proper",
|
||||
email: "mr_proper@gmail.com",
|
||||
timeZone: "Europe/Rome",
|
||||
language: "it",
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app.getHttpServer())
|
||||
.post("/v2/bookings")
|
||||
.send(body)
|
||||
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.error.message).toEqual(
|
||||
`Missing attendee phone number - it is required by the event type. Pass it as \"attendee.phoneNumber\" string in the request.`
|
||||
);
|
||||
});
|
||||
|
||||
it("should be able create a booking if attendee sms reminder is provided", async () => {
|
||||
const phoneNumber = "+37122222222";
|
||||
const body: CreateBookingInput_2024_08_13 = {
|
||||
start: new Date(Date.UTC(2030, 0, 8, 15, 0, 0)).toISOString(),
|
||||
eventTypeId: eventTypeWithAttendeeSmsReminder.id,
|
||||
attendee: {
|
||||
name: "Mr Proper",
|
||||
email: "mr_proper@gmail.com",
|
||||
timeZone: "Europe/Rome",
|
||||
language: "it",
|
||||
phoneNumber,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app.getHttpServer())
|
||||
.post("/v2/bookings")
|
||||
.send(body)
|
||||
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
|
||||
.expect(201);
|
||||
|
||||
const responseBody: CreateBookingOutput_2024_08_13 = response.body;
|
||||
expect(responseBody.status).toEqual(SUCCESS_STATUS);
|
||||
expect(responseBody.data).toBeDefined();
|
||||
expect(responseDataIsBooking(responseBody.data)).toBe(true);
|
||||
|
||||
if (responseDataIsBooking(responseBody.data)) {
|
||||
const data: BookingOutput_2024_08_13 = responseBody.data;
|
||||
expect(data.id).toBeDefined();
|
||||
expect(data.uid).toBeDefined();
|
||||
expect(data.hosts.length).toEqual(1);
|
||||
expect(data.hosts[0].id).toEqual(user.id);
|
||||
expect(data.status).toEqual("accepted");
|
||||
expect(data.start).toEqual(body.start);
|
||||
expect(data.end).toEqual(new Date(Date.UTC(2030, 0, 8, 15, 15, 0)).toISOString());
|
||||
expect(data.duration).toEqual(15);
|
||||
expect(data.eventTypeId).toEqual(eventTypeWithAttendeeSmsReminder.id);
|
||||
expect(data.attendees.length).toEqual(1);
|
||||
expect(data.attendees[0]).toEqual({
|
||||
name: body.attendee.name,
|
||||
email: body.attendee.email,
|
||||
timeZone: body.attendee.timeZone,
|
||||
language: body.attendee.language,
|
||||
phoneNumber: body.attendee.phoneNumber,
|
||||
absent: false,
|
||||
});
|
||||
expect(data.bookingFieldsResponses).toEqual({
|
||||
name: body.attendee.name,
|
||||
email: body.attendee.email,
|
||||
attendeePhoneNumber: body.attendee.phoneNumber,
|
||||
smsReminderNumber: body.attendee.phoneNumber,
|
||||
});
|
||||
const dbBooking = await bookingsRepositoryFixture.getById(data.id);
|
||||
expect(dbBooking?.smsReminderNumber).toEqual(phoneNumber);
|
||||
const dbWorkflowReminder = await workflowReminderRepositoryFixture.getByBookingUid(data.uid);
|
||||
expect(dbWorkflowReminder?.method).toEqual("SMS");
|
||||
} else {
|
||||
throw new Error("Invalid response data");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function responseDataIsRecurranceBooking(data: any): data is RecurringBookingOutput_2024_08_13 {
|
||||
return (
|
||||
!Array.isArray(data) &&
|
||||
|
||||
@@ -20,6 +20,7 @@ import { UsersRepository, UserWithProfile } from "@/modules/users/users.reposito
|
||||
import { ConflictException, Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||
import { BadRequestException } from "@nestjs/common";
|
||||
import { Request } from "express";
|
||||
import { DateTime } from "luxon";
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
@@ -65,7 +66,7 @@ const eventTypeBookingFieldSchema = z.object({
|
||||
editable: z.string(),
|
||||
});
|
||||
|
||||
const eventTypeBookingFieldsSchema = z.array(eventTypeBookingFieldSchema);
|
||||
export const eventTypeBookingFieldsSchema = z.array(eventTypeBookingFieldSchema);
|
||||
|
||||
export type EventTypeWithOwnerAndTeam = EventType & { owner: User | null; team: Team | null };
|
||||
|
||||
@@ -171,25 +172,30 @@ export class BookingsService_2024_08_13 {
|
||||
}
|
||||
|
||||
async hasRequiredBookingFieldsResponses(body: CreateBookingInput, eventType: EventType | null) {
|
||||
const bookingFields = { ...body.bookingFieldsResponses, attendeePhoneNumber: body.attendee.phoneNumber };
|
||||
const bookingFields: Record<string, unknown> = {
|
||||
...body.bookingFieldsResponses,
|
||||
attendeePhoneNumber: body.attendee.phoneNumber,
|
||||
smsReminderNumber: body.attendee.phoneNumber,
|
||||
};
|
||||
if (!eventType?.bookingFields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// note(Lauris): we filter out system fields, because some of them are set by default and name and email are passed in the body.attendee
|
||||
// note(Lauris): we filter out system fields, because some of them are set by default and name and email are passed in the body.attendee. Only exception
|
||||
// is smsReminderNumber, because if it is required and not passed sms workflow won't work.
|
||||
const eventTypeBookingFields = eventTypeBookingFieldsSchema
|
||||
.parse(eventType.bookingFields)
|
||||
.filter((field) => !field.editable.startsWith("system"));
|
||||
.filter((field) => !field.editable.startsWith("system") || field.name === "smsReminderNumber");
|
||||
|
||||
if (!eventTypeBookingFields.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const field of eventTypeBookingFields) {
|
||||
if (field.required && !(field.name in bookingFields)) {
|
||||
if (field.name === "attendeePhoneNumber") {
|
||||
if (field.required && (bookingFields[field.name] === null || bookingFields[field.name] === undefined)) {
|
||||
if (field.name === "attendeePhoneNumber" || field.name === "smsReminderNumber") {
|
||||
throw new BadRequestException(
|
||||
`Missing attendee phone number - it is required by the event type. Pass it as "attendee.phoneNumber" in the request.`
|
||||
`Missing attendee phone number - it is required by the event type. Pass it as "attendee.phoneNumber" string in the request.`
|
||||
);
|
||||
}
|
||||
throw new BadRequestException(
|
||||
@@ -376,7 +382,7 @@ export class BookingsService_2024_08_13 {
|
||||
queryParams.attendeeEmail = await this.getAttendeeEmail(queryParams.attendeeEmail, user);
|
||||
}
|
||||
|
||||
const fetchedBookings: { bookings: { id: number }[] } = await getAllUserBookings({
|
||||
const fetchedBookings: { bookings: { id: number }[]; totalCount: number } = await getAllUserBookings({
|
||||
bookingListingByStatus: queryParams.status || [],
|
||||
skip: queryParams.skip ?? 0,
|
||||
take: queryParams.take ?? 100,
|
||||
@@ -432,7 +438,29 @@ export class BookingsService_2024_08_13 {
|
||||
}
|
||||
}
|
||||
|
||||
return formattedBookings;
|
||||
const skip = Math.abs(queryParams?.skip ?? 0);
|
||||
const take = Math.abs(queryParams?.take ?? 100);
|
||||
const itemsPerPage = take;
|
||||
const totalPages = itemsPerPage !== 0 ? Math.ceil(fetchedBookings.totalCount / itemsPerPage) : 0;
|
||||
const currentPage = Math.floor(skip / itemsPerPage) + 1;
|
||||
const hasNextPage = skip + itemsPerPage < fetchedBookings.totalCount;
|
||||
const hasPreviousPage = skip > 0;
|
||||
return {
|
||||
bookings: formattedBookings,
|
||||
pagination: {
|
||||
totalItems: fetchedBookings.totalCount,
|
||||
// clamp remainingItems between 0 and totalCount
|
||||
remainingItems: Math.min(
|
||||
Math.max(fetchedBookings.totalCount - (skip + take), 0),
|
||||
fetchedBookings.totalCount
|
||||
),
|
||||
itemsPerPage: itemsPerPage,
|
||||
currentPage: currentPage,
|
||||
totalPages: totalPages,
|
||||
hasNextPage: hasNextPage,
|
||||
hasPreviousPage: hasPreviousPage,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getAttendeeEmail(queryParamsAttendeeEmail: string, user: { id: number }) {
|
||||
@@ -572,6 +600,20 @@ export class BookingsService_2024_08_13 {
|
||||
async markAbsent(bookingUid: string, bookingOwnerId: number, body: MarkAbsentBookingInput_2024_08_13) {
|
||||
const bodyTransformed = this.inputService.transformInputMarkAbsentBooking(body);
|
||||
const bookingBefore = await this.bookingsRepository.getByUid(bookingUid);
|
||||
|
||||
if (!bookingBefore) {
|
||||
throw new NotFoundException(`Booking with uid=${bookingUid} not found.`);
|
||||
}
|
||||
|
||||
const nowUtc = DateTime.utc();
|
||||
const bookingStartTimeUtc = DateTime.fromJSDate(bookingBefore.startTime, { zone: "utc" });
|
||||
|
||||
if (nowUtc < bookingStartTimeUtc) {
|
||||
throw new BadRequestException(
|
||||
`Bookings can only be marked as absent after their scheduled start time. Current time in UTC+0: ${nowUtc.toISO()}, Booking start time in UTC+0: ${bookingStartTimeUtc.toISO()}`
|
||||
);
|
||||
}
|
||||
|
||||
const platformClientParams = bookingBefore?.eventTypeId
|
||||
? await this.platformBookingsService.getOAuthClientParams(bookingBefore.eventTypeId)
|
||||
: undefined;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/bookings.repository";
|
||||
import { EventTypeWithOwnerAndTeam } from "@/ee/bookings/2024-08-13/services/bookings.service";
|
||||
import {
|
||||
eventTypeBookingFieldsSchema,
|
||||
EventTypeWithOwnerAndTeam,
|
||||
} from "@/ee/bookings/2024-08-13/services/bookings.service";
|
||||
import {
|
||||
bookingResponsesSchema,
|
||||
seatedBookingDataSchema,
|
||||
@@ -159,6 +162,12 @@ export class InputBookingsService_2024_08_13 {
|
||||
this.isBookingLocationWithEventTypeLocations(inputLocation, eventType);
|
||||
const location = inputLocation ? this.transformLocation(inputLocation) : undefined;
|
||||
|
||||
const needsSmsReminderNumber = eventType.bookingFields
|
||||
? eventTypeBookingFieldsSchema
|
||||
.parse(eventType.bookingFields)
|
||||
.find((field) => field.name === "smsReminderNumber")
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
start: startTime.toISO(),
|
||||
end: endTime.toISO(),
|
||||
@@ -174,6 +183,7 @@ export class InputBookingsService_2024_08_13 {
|
||||
name: inputBooking.attendee.name,
|
||||
email: attendeeEmail ?? "",
|
||||
attendeePhoneNumber: inputBooking.attendee.phoneNumber,
|
||||
smsReminderNumber: needsSmsReminderNumber ? inputBooking.attendee.phoneNumber : undefined,
|
||||
guests,
|
||||
location,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { OrganizerIntegrationLocation } from "@calcom/lib";
|
||||
import { OrganizerIntegrationLocation } from "@calcom/lib/event-types/transformers/internal/locations";
|
||||
|
||||
type BaseEventType = {
|
||||
length: number;
|
||||
|
||||
@@ -8,7 +8,6 @@ import { InputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_
|
||||
import { OutputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/output-event-types.service";
|
||||
import { SchedulesRepository_2024_06_11 } from "@/ee/schedules/schedules_2024_06_11/schedules.repository";
|
||||
import { AppsRepository } from "@/modules/apps/apps.repository";
|
||||
import { ConferencingModule } from "@/modules/conferencing/conferencing.module";
|
||||
import { CredentialsRepository } from "@/modules/credentials/credentials.repository";
|
||||
import { MembershipsModule } from "@/modules/memberships/memberships.module";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
@@ -19,7 +18,7 @@ import { UsersRepository } from "@/modules/users/users.repository";
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, MembershipsModule, TokensModule, SelectedCalendarsModule, ConferencingModule],
|
||||
imports: [PrismaModule, MembershipsModule, TokensModule, SelectedCalendarsModule],
|
||||
providers: [
|
||||
EventTypesRepository_2024_06_14,
|
||||
EventTypesService_2024_06_14,
|
||||
|
||||
+29
-11
@@ -5,6 +5,9 @@ import { ConferencingService } from "@/modules/conferencing/services/conferencin
|
||||
import { UserWithProfile } from "@/modules/users/users.repository";
|
||||
import { Injectable, BadRequestException } from "@nestjs/common";
|
||||
|
||||
import { CONFERENCING_APPS } from "@calcom/platform-constants";
|
||||
import { getUsersCredentials } from "@calcom/platform-libraries";
|
||||
import { getApps } from "@calcom/platform-libraries/app-store";
|
||||
import {
|
||||
transformBookingFieldsApiToInternal,
|
||||
transformLocationsApiToInternal,
|
||||
@@ -50,8 +53,7 @@ interface ValidationContext {
|
||||
export class InputEventTypesService_2024_06_14 {
|
||||
constructor(
|
||||
private readonly eventTypesRepository: EventTypesRepository_2024_06_14,
|
||||
private readonly calendarsService: CalendarsService,
|
||||
private readonly conferencingService: ConferencingService
|
||||
private readonly calendarsService: CalendarsService
|
||||
) {}
|
||||
|
||||
async transformAndValidateCreateEventTypeInput(
|
||||
@@ -104,13 +106,6 @@ export class InputEventTypesService_2024_06_14 {
|
||||
}
|
||||
|
||||
transformInputCreateEventType(inputEventType: CreateEventTypeInput_2024_06_14) {
|
||||
const defaultLocations: CreateEventTypeInput_2024_06_14["locations"] = [
|
||||
{
|
||||
type: "integration",
|
||||
integration: "cal-video",
|
||||
},
|
||||
];
|
||||
|
||||
const {
|
||||
lengthInMinutes,
|
||||
lengthInMinutesOptions,
|
||||
@@ -130,10 +125,11 @@ export class InputEventTypesService_2024_06_14 {
|
||||
} = inputEventType;
|
||||
const confirmationPolicyTransformed = this.transformInputConfirmationPolicy(confirmationPolicy);
|
||||
|
||||
const locationsTransformed = locations?.length ? this.transformInputLocations(locations) : undefined;
|
||||
const eventType = {
|
||||
...rest,
|
||||
length: lengthInMinutes,
|
||||
locations: this.transformInputLocations(locations || defaultLocations),
|
||||
locations: locationsTransformed,
|
||||
bookingFields: this.transformInputBookingFields(bookingFields),
|
||||
bookingLimits: bookingLimitsCount ? this.transformInputIntervalLimits(bookingLimitsCount) : undefined,
|
||||
durationLimits: bookingLimitsDuration
|
||||
@@ -463,10 +459,32 @@ export class InputEventTypesService_2024_06_14 {
|
||||
if (location.type === "integration") {
|
||||
// cal-video is global, so we can skip this check
|
||||
if (location.integration !== "cal-video") {
|
||||
await this.conferencingService.checkAppIsValidAndConnected(user, location.integration);
|
||||
await this.checkAppIsValidAndConnected(user, location.integration);
|
||||
}
|
||||
}
|
||||
}) ?? []
|
||||
);
|
||||
}
|
||||
|
||||
async checkAppIsValidAndConnected(user: UserWithProfile, appSlug: string) {
|
||||
const conferencingApps = ["google-meet", "office365-video", "zoom"];
|
||||
if (!conferencingApps.includes(appSlug)) {
|
||||
throw new BadRequestException("Invalid app, available apps are: ", conferencingApps.join(", "));
|
||||
}
|
||||
|
||||
if (appSlug === "office365-video") {
|
||||
appSlug = "msteams";
|
||||
}
|
||||
|
||||
const credentials = await getUsersCredentials(user);
|
||||
|
||||
const foundApp = getApps(credentials, true).filter((app) => app.slug === appSlug)[0];
|
||||
|
||||
const appLocation = foundApp?.appData?.location;
|
||||
|
||||
if (!foundApp || !appLocation) {
|
||||
throw new BadRequestException(`${appSlug} not connected.`);
|
||||
}
|
||||
return foundApp.credential;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ if (process.env.SENTRY_DSN) {
|
||||
// Ensure to call this before requiring any other modules!
|
||||
Sentry.init({
|
||||
dsn: getEnv("SENTRY_DSN"),
|
||||
integrations: [nodeProfilingIntegration()],
|
||||
integrations: [nodeProfilingIntegration(), Sentry.prismaIntegration()],
|
||||
// Performance Monitoring
|
||||
tracesSampleRate: getEnv("SENTRY_TRACES_SAMPLE_RATE") ?? 1.0, // Capture 100% of the transactions
|
||||
// Set sampling rate for profiling - this is relative to tracesSampleRate
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/bookings.repository";
|
||||
import { BillingProcessor } from "@/modules/billing/billing.processor";
|
||||
import { BillingRepository } from "@/modules/billing/billing.repository";
|
||||
import { BillingController } from "@/modules/billing/controllers/billing.controller";
|
||||
@@ -5,6 +6,7 @@ import { BillingConfigService } from "@/modules/billing/services/billing.config.
|
||||
import { BillingService } from "@/modules/billing/services/billing.service";
|
||||
import { ManagedOrganizationsBillingService } from "@/modules/billing/services/managed-organizations.billing.service";
|
||||
import { MembershipsModule } from "@/modules/memberships/memberships.module";
|
||||
import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository";
|
||||
import { OrganizationsModule } from "@/modules/organizations/organizations.module";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { StripeModule } from "@/modules/stripe/stripe.module";
|
||||
@@ -33,6 +35,8 @@ import { Module } from "@nestjs/common";
|
||||
BillingRepository,
|
||||
BillingProcessor,
|
||||
ManagedOrganizationsBillingService,
|
||||
OAuthClientRepository,
|
||||
BookingsRepository_2024_08_13,
|
||||
],
|
||||
exports: [BillingService, BillingRepository, ManagedOrganizationsBillingService],
|
||||
controllers: [BillingController],
|
||||
|
||||
@@ -15,12 +15,21 @@ export class BillingRepository {
|
||||
},
|
||||
});
|
||||
|
||||
async getBillingForTeamBySubscriptionId(subscriptionId: string) {
|
||||
return this.dbRead.prisma.platformBilling.findFirst({
|
||||
where: {
|
||||
subscriptionId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateTeamBilling(
|
||||
teamId: number,
|
||||
billingStart: number,
|
||||
billingEnd: number,
|
||||
plan: PlatformPlan,
|
||||
subscriptionId?: string
|
||||
subscriptionId?: string,
|
||||
priceId?: string
|
||||
) {
|
||||
return this.dbWrite.prisma.platformBilling.update({
|
||||
where: {
|
||||
@@ -32,6 +41,7 @@ export class BillingRepository {
|
||||
subscriptionId,
|
||||
plan: plan.toString(),
|
||||
overdue: false,
|
||||
priceId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,6 +127,9 @@ export class BillingController {
|
||||
case "customer.subscription.deleted":
|
||||
await this.billingService.handleStripeSubscriptionDeleted(event);
|
||||
break;
|
||||
case "invoice.created":
|
||||
await this.billingService.handleStripeSubscriptionForActiveManagedUsers(event);
|
||||
break;
|
||||
case "invoice.payment_failed":
|
||||
await this.billingService.handleStripePaymentFailed(event);
|
||||
break;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { AppConfig } from "@/config/type";
|
||||
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/bookings.repository";
|
||||
import { BILLING_QUEUE, INCREMENT_JOB, IncrementJobDataType } from "@/modules/billing/billing.processor";
|
||||
import { BillingRepository } from "@/modules/billing/billing.repository";
|
||||
import { BillingConfigService } from "@/modules/billing/services/billing.config.service";
|
||||
import { PlatformPlan } from "@/modules/billing/types";
|
||||
import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository";
|
||||
import { OrganizationsRepository } from "@/modules/organizations/index/organizations.repository";
|
||||
import { StripeService } from "@/modules/stripe/stripe.service";
|
||||
import { UsersRepository } from "@/modules/users/users.repository";
|
||||
import { InjectQueue } from "@nestjs/bull";
|
||||
import {
|
||||
BadRequestException,
|
||||
@@ -30,6 +33,9 @@ export class BillingService implements OnModuleDestroy {
|
||||
private readonly billingRepository: BillingRepository,
|
||||
private readonly configService: ConfigService<AppConfig>,
|
||||
private readonly billingConfigService: BillingConfigService,
|
||||
private readonly usersRepository: UsersRepository,
|
||||
private readonly oAuthClientRepository: OAuthClientRepository,
|
||||
private readonly bookingsRepository: BookingsRepository_2024_08_13,
|
||||
@InjectQueue(BILLING_QUEUE) private readonly billingQueue: Queue
|
||||
) {
|
||||
this.webAppUrl = this.configService.get("app.baseUrl", { infer: true }) ?? "https://app.cal.com";
|
||||
@@ -119,7 +125,7 @@ export class BillingService implements OnModuleDestroy {
|
||||
return url;
|
||||
}
|
||||
|
||||
async setSubscriptionForTeam(teamId: number, subscriptionId: string, plan: PlatformPlan) {
|
||||
async setPerBookingSubscriptionForTeam(teamId: number, subscriptionId: string, plan: PlatformPlan) {
|
||||
const billingCycleStart = DateTime.now().get("day");
|
||||
const billingCycleEnd = DateTime.now().plus({ month: 1 }).get("day");
|
||||
|
||||
@@ -132,6 +138,25 @@ export class BillingService implements OnModuleDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
async setPerActiveUserSubscriptionForTeam(
|
||||
teamId: number,
|
||||
subscriptionId: string,
|
||||
plan: PlatformPlan,
|
||||
priceId: string
|
||||
) {
|
||||
const billingCycleStart = DateTime.now().get("day");
|
||||
const billingCycleEnd = DateTime.now().plus({ month: 1 }).get("day");
|
||||
|
||||
return this.billingRepository.updateTeamBilling(
|
||||
teamId,
|
||||
billingCycleStart,
|
||||
billingCycleEnd,
|
||||
plan,
|
||||
subscriptionId,
|
||||
priceId
|
||||
);
|
||||
}
|
||||
|
||||
async handleStripeSubscriptionDeleted(event: Stripe.Event) {
|
||||
const subscription = event.data.object as Stripe.Subscription;
|
||||
const teamId = subscription?.metadata?.teamId;
|
||||
@@ -204,9 +229,19 @@ export class BillingService implements OnModuleDestroy {
|
||||
this.logger.log("Webhook received but not pertaining to Platform, discarding.");
|
||||
return;
|
||||
}
|
||||
const isPriceIdPresent = Boolean(checkoutSession.metadata?.priceId);
|
||||
|
||||
if (checkoutSession.mode === "subscription") {
|
||||
await this.setSubscriptionForTeam(
|
||||
if (checkoutSession.mode === "subscription" && isPriceIdPresent) {
|
||||
await this.setPerActiveUserSubscriptionForTeam(
|
||||
teamId,
|
||||
checkoutSession.subscription as string,
|
||||
PlatformPlan[plan.toUpperCase() as keyof typeof PlatformPlan],
|
||||
checkoutSession.metadata?.priceId
|
||||
);
|
||||
}
|
||||
|
||||
if (checkoutSession.mode === "subscription" && !isPriceIdPresent) {
|
||||
await this.setPerBookingSubscriptionForTeam(
|
||||
teamId,
|
||||
checkoutSession.subscription as string,
|
||||
PlatformPlan[plan.toUpperCase() as keyof typeof PlatformPlan]
|
||||
@@ -220,6 +255,67 @@ export class BillingService implements OnModuleDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
async handleStripeSubscriptionForActiveManagedUsers(event: Stripe.Event) {
|
||||
const invoice = event.data.object as Stripe.Invoice;
|
||||
const subscriptionId = this.getSubscriptionIdFromInvoice(invoice);
|
||||
|
||||
if (!subscriptionId) {
|
||||
throw new NotFoundException("No subscription found for team");
|
||||
}
|
||||
|
||||
const teamWithBilling = await this.billingRepository.getBillingForTeamBySubscriptionId(subscriptionId);
|
||||
|
||||
if (teamWithBilling?.plan === "PER_ACTIVE_USER") {
|
||||
const activeManagedUsersCount = await this.getActiveManagedUsersCount(
|
||||
subscriptionId,
|
||||
new Date(invoice.period_start * 1000),
|
||||
new Date(invoice.period_end * 1000)
|
||||
);
|
||||
|
||||
await this.stripeService.getStripe().subscriptions.update(subscriptionId, {
|
||||
items: [
|
||||
{
|
||||
quantity: activeManagedUsersCount > 0 ? activeManagedUsersCount : 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async getActiveManagedUsersCount(subscriptionId: string, invoiceStart: Date, invoiceEnd: Date) {
|
||||
const managedUsersEmails = await this.usersRepository.getOrgsManagedUserEmailsBySubscriptionId(
|
||||
subscriptionId
|
||||
);
|
||||
|
||||
if (!managedUsersEmails) return 0;
|
||||
|
||||
if (!invoiceStart || !invoiceEnd) {
|
||||
this.logger.log("Invoice period start or end date is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const activeManagedUserEmailsAsHost = await this.usersRepository.getActiveManagedUsersAsHost(
|
||||
subscriptionId,
|
||||
invoiceStart,
|
||||
invoiceEnd
|
||||
);
|
||||
|
||||
const activeHostEmails = activeManagedUserEmailsAsHost.map((email) => email.email);
|
||||
const notActiveHostEmails = managedUsersEmails
|
||||
.filter((email) => !activeHostEmails.includes(email.email))
|
||||
.map((email) => email.email);
|
||||
|
||||
if (notActiveHostEmails.length === 0) return activeManagedUserEmailsAsHost.length;
|
||||
|
||||
const activeManagedUserEmailsAsAttendee = await this.usersRepository.getActiveManagedUsersAsAttendee(
|
||||
notActiveHostEmails,
|
||||
invoiceStart,
|
||||
invoiceEnd
|
||||
);
|
||||
|
||||
return activeManagedUserEmailsAsAttendee.length + activeManagedUserEmailsAsHost.length;
|
||||
}
|
||||
|
||||
async updateStripeSubscriptionForTeam(teamId: number, plan: PlatformPlan) {
|
||||
const teamWithBilling = await this.teamsRepository.findByIdIncludeBilling(teamId);
|
||||
|
||||
@@ -263,7 +359,7 @@ export class BillingService implements OnModuleDestroy {
|
||||
proration_behavior: "create_prorations",
|
||||
});
|
||||
|
||||
await this.setSubscriptionForTeam(
|
||||
await this.setPerBookingSubscriptionForTeam(
|
||||
teamId,
|
||||
teamWithBilling?.platformBilling?.subscriptionId,
|
||||
PlatformPlan[plan.toUpperCase() as keyof typeof PlatformPlan]
|
||||
|
||||
@@ -4,6 +4,7 @@ export enum PlatformPlan {
|
||||
ESSENTIALS = "ESSENTIALS",
|
||||
SCALE = "SCALE",
|
||||
ENTERPRISE = "ENTERPRISE",
|
||||
PER_ACTIVE_USER = "PER_ACTIVE_USER",
|
||||
}
|
||||
|
||||
export type PlatformPlanType = "FREE" | "STARTER" | "ESSENTIALS" | "SCALE" | "ENTERPRISE";
|
||||
export type PlatformPlanType = "FREE" | "STARTER" | "ESSENTIALS" | "SCALE" | "ENTERPRISE" | "PER_ACTIVE_USER";
|
||||
|
||||
@@ -45,7 +45,7 @@ export class OrganizationsBookingsController {
|
||||
): Promise<GetBookingsOutput_2024_08_13> {
|
||||
const { userIds, ...restParams } = queryParams;
|
||||
|
||||
const bookings = await this.bookingsService.getBookings(
|
||||
const { bookings, pagination } = await this.bookingsService.getBookings(
|
||||
{ ...restParams },
|
||||
{ email: user.email, id: user.id, orgId },
|
||||
userIds
|
||||
@@ -54,6 +54,7 @@ export class OrganizationsBookingsController {
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: bookings,
|
||||
pagination,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { InputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/input-event-types.service";
|
||||
import { ConferencingRepository } from "@/modules/conferencing/repositories/conferencing.repository";
|
||||
import { OrganizationsConferencingService } from "@/modules/organizations/conferencing/services/organizations-conferencing.service";
|
||||
import { TeamsEventTypesRepository } from "@/modules/teams/event-types/teams-event-types.repository";
|
||||
import { TeamsRepository } from "@/modules/teams/teams/teams.repository";
|
||||
@@ -27,7 +28,8 @@ export class InputOrganizationsEventTypesService {
|
||||
private readonly teamsRepository: TeamsRepository,
|
||||
private readonly usersRepository: UsersRepository,
|
||||
private readonly teamsEventTypesRepository: TeamsEventTypesRepository,
|
||||
private readonly conferencingService: OrganizationsConferencingService
|
||||
private readonly conferencingService: OrganizationsConferencingService,
|
||||
private readonly conferencingRepository: ConferencingRepository
|
||||
) {}
|
||||
async transformAndValidateCreateTeamEventTypeInput(
|
||||
userId: number,
|
||||
@@ -306,6 +308,22 @@ export class InputOrganizationsEventTypesService {
|
||||
}) ?? []
|
||||
);
|
||||
}
|
||||
|
||||
async checkAppIsValidAndConnected(teamId: number, app: string) {
|
||||
const conferencingApps = ["google-meet", "office365-video", "zoom"];
|
||||
if (!conferencingApps.includes(app)) {
|
||||
throw new BadRequestException("Invalid app, available apps are: ", conferencingApps.join(", "));
|
||||
}
|
||||
if (app === "office365-video") {
|
||||
app = "msteams";
|
||||
}
|
||||
const credential = await this.conferencingRepository.findTeamConferencingApp(teamId, app);
|
||||
|
||||
if (!credential) {
|
||||
throw new BadRequestException(`${app} not connected.`);
|
||||
}
|
||||
return credential;
|
||||
}
|
||||
}
|
||||
|
||||
function getPriorityValue(priority: keyof typeof HostPriority): number {
|
||||
|
||||
+196
-10
@@ -6,6 +6,7 @@ import { CreateOrgMembershipOutput } from "@/modules/organizations/memberships/o
|
||||
import { DeleteOrgMembership } from "@/modules/organizations/memberships/outputs/delete-membership.output";
|
||||
import { GetAllOrgMemberships } from "@/modules/organizations/memberships/outputs/get-all-memberships.output";
|
||||
import { GetOrgMembership } from "@/modules/organizations/memberships/outputs/get-membership.output";
|
||||
import { OrgUserAttribute } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { UpdateOrgMembership } from "@/modules/organizations/memberships/outputs/update-membership.output";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
@@ -14,17 +15,16 @@ import { UsersModule } from "@/modules/users/users.module";
|
||||
import { INestApplication } from "@nestjs/common";
|
||||
import { NestExpressApplication } from "@nestjs/platform-express";
|
||||
import { Test } from "@nestjs/testing";
|
||||
import { User } from "@prisma/client";
|
||||
import { Attribute, AttributeOption, User } from "@prisma/client";
|
||||
import * as request from "supertest";
|
||||
import { AttributeRepositoryFixture } from "test/fixtures/repository/attributes.repository.fixture";
|
||||
import { MembershipRepositoryFixture } from "test/fixtures/repository/membership.repository.fixture";
|
||||
import { OrganizationRepositoryFixture } from "test/fixtures/repository/organization.repository.fixture";
|
||||
import { TeamRepositoryFixture } from "test/fixtures/repository/team.repository.fixture";
|
||||
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
|
||||
import { randomString } from "test/utils/randomString";
|
||||
import { withApiAuth } from "test/utils/withApiAuth";
|
||||
|
||||
import { SUCCESS_STATUS } from "@calcom/platform-constants";
|
||||
import { ApiSuccessResponse } from "@calcom/platform-types";
|
||||
import { Membership, Team } from "@calcom/prisma/client";
|
||||
|
||||
describe("Organizations Memberships Endpoints", () => {
|
||||
@@ -33,7 +33,8 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
|
||||
let userRepositoryFixture: UserRepositoryFixture;
|
||||
let organizationsRepositoryFixture: OrganizationRepositoryFixture;
|
||||
let membershipsRepositoryFixture: MembershipRepositoryFixture;
|
||||
let membershipRepositoryFixture: MembershipRepositoryFixture;
|
||||
let attributesRepositoryFixture: AttributeRepositoryFixture;
|
||||
|
||||
let org: Team;
|
||||
let membership: Membership;
|
||||
@@ -49,6 +50,17 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
|
||||
let userToInviteViaApi: User;
|
||||
|
||||
let textAttribute: Attribute;
|
||||
let multiSelectAttribute: Attribute;
|
||||
let numberAttribute: Attribute;
|
||||
let singleSelectAttribute: Attribute;
|
||||
|
||||
let textAttributeOption: AttributeOption;
|
||||
let multiSelectAttributeOption: AttributeOption;
|
||||
let multiSelectAttributeOption2: AttributeOption;
|
||||
let numberAttributeOption: AttributeOption;
|
||||
let singleSelectAttributeOption: AttributeOption;
|
||||
|
||||
const metadata = {
|
||||
some: "key",
|
||||
};
|
||||
@@ -64,7 +76,8 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
|
||||
userRepositoryFixture = new UserRepositoryFixture(moduleRef);
|
||||
organizationsRepositoryFixture = new OrganizationRepositoryFixture(moduleRef);
|
||||
membershipsRepositoryFixture = new MembershipRepositoryFixture(moduleRef);
|
||||
membershipRepositoryFixture = new MembershipRepositoryFixture(moduleRef);
|
||||
attributesRepositoryFixture = new AttributeRepositoryFixture(moduleRef);
|
||||
|
||||
user = await userRepositoryFixture.create({
|
||||
email: userEmail,
|
||||
@@ -91,16 +104,42 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
isOrganization: true,
|
||||
});
|
||||
|
||||
membership = await membershipsRepositoryFixture.create({
|
||||
await setupAttributes();
|
||||
|
||||
membership = await membershipRepositoryFixture.create({
|
||||
role: "ADMIN",
|
||||
user: { connect: { id: user.id } },
|
||||
team: { connect: { id: org.id } },
|
||||
});
|
||||
|
||||
membership2 = await membershipsRepositoryFixture.create({
|
||||
membership2 = await membershipRepositoryFixture.create({
|
||||
role: "MEMBER",
|
||||
user: { connect: { id: user2.id } },
|
||||
team: { connect: { id: org.id } },
|
||||
AttributeToUser: {
|
||||
create: [
|
||||
{
|
||||
attributeOption: { connect: { id: textAttributeOption.id } },
|
||||
weight: 100,
|
||||
},
|
||||
{
|
||||
attributeOption: { connect: { id: multiSelectAttributeOption.id } },
|
||||
weight: 100,
|
||||
},
|
||||
{
|
||||
attributeOption: { connect: { id: multiSelectAttributeOption2.id } },
|
||||
weight: null,
|
||||
},
|
||||
{
|
||||
attributeOption: { connect: { id: numberAttributeOption.id } },
|
||||
weight: 100,
|
||||
},
|
||||
{
|
||||
attributeOption: { connect: { id: singleSelectAttributeOption.id } },
|
||||
weight: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
@@ -109,6 +148,87 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
await app.init();
|
||||
});
|
||||
|
||||
async function setupAttributes() {
|
||||
textAttribute = await attributesRepositoryFixture.create({
|
||||
team: { connect: { id: org.id } },
|
||||
type: "TEXT",
|
||||
name: "team",
|
||||
slug: `team-${randomString()}`,
|
||||
enabled: true,
|
||||
usersCanEditRelation: false,
|
||||
isWeightsEnabled: false,
|
||||
isLocked: false,
|
||||
});
|
||||
|
||||
multiSelectAttribute = await attributesRepositoryFixture.create({
|
||||
team: { connect: { id: org.id } },
|
||||
type: "MULTI_SELECT",
|
||||
name: "skills",
|
||||
slug: `skills-${randomString()}`,
|
||||
enabled: true,
|
||||
usersCanEditRelation: false,
|
||||
isWeightsEnabled: false,
|
||||
isLocked: false,
|
||||
});
|
||||
|
||||
numberAttribute = await attributesRepositoryFixture.create({
|
||||
team: { connect: { id: org.id } },
|
||||
type: "NUMBER",
|
||||
name: "age",
|
||||
slug: `age-${randomString()}`,
|
||||
enabled: true,
|
||||
usersCanEditRelation: false,
|
||||
isWeightsEnabled: false,
|
||||
isLocked: false,
|
||||
});
|
||||
|
||||
singleSelectAttribute = await attributesRepositoryFixture.create({
|
||||
team: { connect: { id: org.id } },
|
||||
type: "SINGLE_SELECT",
|
||||
name: "frontend",
|
||||
slug: `frontend-${randomString()}`,
|
||||
enabled: true,
|
||||
usersCanEditRelation: false,
|
||||
isWeightsEnabled: false,
|
||||
isLocked: false,
|
||||
});
|
||||
|
||||
textAttributeOption = await attributesRepositoryFixture.createOption({
|
||||
attribute: { connect: { id: textAttribute.id } },
|
||||
value: "coders",
|
||||
slug: "coders",
|
||||
isGroup: false,
|
||||
});
|
||||
|
||||
multiSelectAttributeOption = await attributesRepositoryFixture.createOption({
|
||||
attribute: { connect: { id: multiSelectAttribute.id } },
|
||||
value: "javascript",
|
||||
slug: "javascript",
|
||||
isGroup: false,
|
||||
});
|
||||
|
||||
multiSelectAttributeOption2 = await attributesRepositoryFixture.createOption({
|
||||
attribute: { connect: { id: multiSelectAttribute.id } },
|
||||
value: "typescript",
|
||||
slug: "typescript",
|
||||
isGroup: false,
|
||||
});
|
||||
|
||||
numberAttributeOption = await attributesRepositoryFixture.createOption({
|
||||
attribute: { connect: { id: numberAttribute.id } },
|
||||
value: "18",
|
||||
slug: "18",
|
||||
isGroup: false,
|
||||
});
|
||||
|
||||
singleSelectAttributeOption = await attributesRepositoryFixture.createOption({
|
||||
attribute: { connect: { id: singleSelectAttribute.id } },
|
||||
value: "yes",
|
||||
slug: "yes",
|
||||
isGroup: false,
|
||||
});
|
||||
}
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(userRepositoryFixture).toBeDefined();
|
||||
expect(organizationsRepositoryFixture).toBeDefined();
|
||||
@@ -139,9 +259,54 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
expect(responseBody.data[1].user.email).toEqual(user2.email);
|
||||
expect(responseBody.data[1].user.username).toEqual(user2.username);
|
||||
expect(responseBody.data[1].teamId).toEqual(org.id);
|
||||
userHasCorrectAttributes(responseBody.data[1].attributes);
|
||||
});
|
||||
});
|
||||
|
||||
function userHasCorrectAttributes(attributes: OrgUserAttribute[]) {
|
||||
expect(attributes.length).toEqual(4);
|
||||
const responseNumberAttribute = attributes.find((attr) => attr.type === "number");
|
||||
const responseSingleSelectAttribute = attributes.find((attr) => attr.type === "singleSelect");
|
||||
const responseMultiSelectAttribute = attributes.find((attr) => attr.type === "multiSelect");
|
||||
const responseTextAttribute = attributes.find((attr) => attr.type === "text");
|
||||
expect(responseNumberAttribute).toEqual({
|
||||
id: numberAttribute.id,
|
||||
name: numberAttribute.name,
|
||||
optionId: numberAttributeOption.id,
|
||||
option: +numberAttributeOption.value,
|
||||
type: "number",
|
||||
});
|
||||
expect(responseSingleSelectAttribute).toEqual({
|
||||
id: singleSelectAttribute.id,
|
||||
name: singleSelectAttribute.name,
|
||||
optionId: singleSelectAttributeOption.id,
|
||||
option: singleSelectAttributeOption.value,
|
||||
type: "singleSelect",
|
||||
});
|
||||
expect(responseMultiSelectAttribute).toEqual({
|
||||
id: multiSelectAttribute.id,
|
||||
name: multiSelectAttribute.name,
|
||||
options: [
|
||||
{
|
||||
optionId: multiSelectAttributeOption2.id,
|
||||
option: multiSelectAttributeOption2.value,
|
||||
},
|
||||
{
|
||||
optionId: multiSelectAttributeOption.id,
|
||||
option: multiSelectAttributeOption.value,
|
||||
},
|
||||
],
|
||||
type: "multiSelect",
|
||||
});
|
||||
expect(responseTextAttribute).toEqual({
|
||||
id: textAttribute.id,
|
||||
name: textAttribute.name,
|
||||
optionId: textAttributeOption.id,
|
||||
option: textAttributeOption.value,
|
||||
type: "text",
|
||||
});
|
||||
}
|
||||
|
||||
it("should get all the memberships of the org paginated", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/organizations/${org.id}/memberships?skip=1&take=1`)
|
||||
@@ -182,6 +347,25 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should get the membership of the org", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/organizations/${org.id}/memberships/${membership2.id}`)
|
||||
.expect(200)
|
||||
.then((response) => {
|
||||
const responseBody: GetOrgMembership = response.body;
|
||||
expect(responseBody.status).toEqual(SUCCESS_STATUS);
|
||||
expect(responseBody.data.id).toEqual(membership2.id);
|
||||
expect(responseBody.data.userId).toEqual(user2.id);
|
||||
expect(responseBody.data.role).toEqual("MEMBER");
|
||||
expect(responseBody.data.user.bio).toEqual(bio);
|
||||
expect(responseBody.data.user.metadata).toEqual(metadata);
|
||||
expect(responseBody.data.user.email).toEqual(user2.email);
|
||||
expect(responseBody.data.user.username).toEqual(user2.username);
|
||||
expect(responseBody.data.teamId).toEqual(org.id);
|
||||
userHasCorrectAttributes(responseBody.data.attributes);
|
||||
});
|
||||
});
|
||||
|
||||
it("should create the membership of the org", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.post(`/v2/organizations/${org.id}/memberships`)
|
||||
@@ -259,7 +443,8 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
|
||||
let userRepositoryFixture: UserRepositoryFixture;
|
||||
let organizationsRepositoryFixture: OrganizationRepositoryFixture;
|
||||
let membershipsRepositoryFixture: MembershipRepositoryFixture;
|
||||
let membershipRepositoryFixture: MembershipRepositoryFixture;
|
||||
let attributesRepositoryFixture: AttributeRepositoryFixture;
|
||||
|
||||
let org: Team;
|
||||
let membership: Membership;
|
||||
@@ -277,7 +462,8 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
|
||||
userRepositoryFixture = new UserRepositoryFixture(moduleRef);
|
||||
organizationsRepositoryFixture = new OrganizationRepositoryFixture(moduleRef);
|
||||
membershipsRepositoryFixture = new MembershipRepositoryFixture(moduleRef);
|
||||
membershipRepositoryFixture = new MembershipRepositoryFixture(moduleRef);
|
||||
attributesRepositoryFixture = new AttributeRepositoryFixture(moduleRef);
|
||||
|
||||
user = await userRepositoryFixture.create({
|
||||
email: userEmail,
|
||||
@@ -289,7 +475,7 @@ describe("Organizations Memberships Endpoints", () => {
|
||||
isOrganization: true,
|
||||
});
|
||||
|
||||
membership = await membershipsRepositoryFixture.create({
|
||||
membership = await membershipRepositoryFixture.create({
|
||||
role: "MEMBER",
|
||||
user: { connect: { id: user.id } },
|
||||
team: { connect: { id: org.id } },
|
||||
|
||||
+5
-9
@@ -20,7 +20,6 @@ import { GetAllOrgMemberships } from "@/modules/organizations/memberships/output
|
||||
import { GetOrgMembership } from "@/modules/organizations/memberships/outputs/get-membership.output";
|
||||
import { UpdateOrgMembership } from "@/modules/organizations/memberships/outputs/update-membership.output";
|
||||
import { OrganizationsMembershipService } from "@/modules/organizations/memberships/services/organizations-membership.service";
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import {
|
||||
Controller,
|
||||
UseGuards,
|
||||
@@ -36,7 +35,6 @@ import {
|
||||
HttpStatus,
|
||||
} from "@nestjs/common";
|
||||
import { ApiHeader, ApiOperation, ApiTags as DocsTags } from "@nestjs/swagger";
|
||||
import { plainToClass } from "class-transformer";
|
||||
|
||||
import { SUCCESS_STATUS } from "@calcom/platform-constants";
|
||||
import { SkipTakePagination } from "@calcom/platform-types";
|
||||
@@ -70,9 +68,7 @@ export class OrganizationsMembershipsController {
|
||||
);
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: memberships.map((membership) =>
|
||||
plainToClass(TeamMembershipOutput, membership, { strategy: "excludeAll" })
|
||||
),
|
||||
data: memberships,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -88,7 +84,7 @@ export class OrganizationsMembershipsController {
|
||||
const membership = await this.organizationsMembershipService.createOrgMembership(orgId, body);
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: plainToClass(TeamMembershipOutput, membership, { strategy: "excludeAll" }),
|
||||
data: membership,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -105,7 +101,7 @@ export class OrganizationsMembershipsController {
|
||||
const membership = await this.organizationsMembershipService.getOrgMembership(orgId, membershipId);
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: plainToClass(TeamMembershipOutput, membership, { strategy: "excludeAll" }),
|
||||
data: membership,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -122,7 +118,7 @@ export class OrganizationsMembershipsController {
|
||||
const membership = await this.organizationsMembershipService.deleteOrgMembership(orgId, membershipId);
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: plainToClass(TeamMembershipOutput, membership, { strategy: "excludeAll" }),
|
||||
data: membership,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -144,7 +140,7 @@ export class OrganizationsMembershipsController {
|
||||
);
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: plainToClass(TeamMembershipOutput, membership, { strategy: "excludeAll" }),
|
||||
data: membership,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+59
-6
@@ -4,8 +4,31 @@ import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { MembershipUserSelect } from "@/modules/teams/memberships/teams-memberships.repository";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
import { UpdateOrgMembershipDto } from "./inputs/update-organization-membership.input";
|
||||
|
||||
export type DbOrgMembership = Awaited<ReturnType<OrganizationsMembershipRepository["findOrgMembership"]>>;
|
||||
|
||||
const attributeToUserSelect = {
|
||||
createdByDSyncId: true,
|
||||
weight: true,
|
||||
attributeOption: {
|
||||
select: {
|
||||
id: true,
|
||||
value: true,
|
||||
slug: true,
|
||||
attribute: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const satisfies Prisma.AttributeToUserSelect;
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationsMembershipRepository {
|
||||
constructor(private readonly dbRead: PrismaReadService, private readonly dbWrite: PrismaWriteService) {}
|
||||
@@ -16,7 +39,12 @@ export class OrganizationsMembershipRepository {
|
||||
id: membershipId,
|
||||
teamId: organizationId,
|
||||
},
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,7 +54,12 @@ export class OrganizationsMembershipRepository {
|
||||
teamId: organizationId,
|
||||
userId,
|
||||
},
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,7 +69,12 @@ export class OrganizationsMembershipRepository {
|
||||
id: membershipId,
|
||||
teamId: organizationId,
|
||||
},
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,14 +83,24 @@ export class OrganizationsMembershipRepository {
|
||||
create: { ...data, teamId: organizationId },
|
||||
update: { role: data.role, accepted: data.accepted, disableImpersonation: data.disableImpersonation },
|
||||
where: { userId_teamId: { userId: data.userId, teamId: organizationId } },
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
async updateOrgMembership(organizationId: number, membershipId: number, data: UpdateOrgMembershipDto) {
|
||||
return this.dbWrite.prisma.membership.update({
|
||||
data: { ...data },
|
||||
where: { id: membershipId, teamId: organizationId },
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,7 +109,12 @@ export class OrganizationsMembershipRepository {
|
||||
where: {
|
||||
teamId: organizationId,
|
||||
},
|
||||
include: { user: { select: MembershipUserSelect } },
|
||||
include: {
|
||||
user: { select: MembershipUserSelect },
|
||||
AttributeToUser: {
|
||||
select: attributeToUserSelect,
|
||||
},
|
||||
},
|
||||
skip,
|
||||
take,
|
||||
});
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { OrganizationMembershipOutput } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsNotEmptyObject, ValidateNested } from "class-validator";
|
||||
@@ -11,10 +11,10 @@ export class CreateOrgMembershipOutput {
|
||||
status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS;
|
||||
|
||||
@ApiProperty({
|
||||
type: TeamMembershipOutput,
|
||||
type: OrganizationMembershipOutput,
|
||||
})
|
||||
@IsNotEmptyObject()
|
||||
@ValidateNested()
|
||||
@Type(() => TeamMembershipOutput)
|
||||
data!: TeamMembershipOutput;
|
||||
@Type(() => OrganizationMembershipOutput)
|
||||
data!: OrganizationMembershipOutput;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { OrganizationMembershipOutput } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsEnum } from "class-validator";
|
||||
|
||||
@@ -9,5 +9,5 @@ export class DeleteOrgMembership {
|
||||
@IsEnum([SUCCESS_STATUS, ERROR_STATUS])
|
||||
status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS;
|
||||
|
||||
data!: TeamMembershipOutput;
|
||||
data!: OrganizationMembershipOutput;
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { OrganizationMembershipOutput } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsNotEmptyObject, ValidateNested, IsArray } from "class-validator";
|
||||
@@ -11,11 +11,11 @@ export class GetAllOrgMemberships {
|
||||
status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS;
|
||||
|
||||
@ApiProperty({
|
||||
type: TeamMembershipOutput,
|
||||
type: OrganizationMembershipOutput,
|
||||
})
|
||||
@IsNotEmptyObject()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => TeamMembershipOutput)
|
||||
@Type(() => OrganizationMembershipOutput)
|
||||
@IsArray()
|
||||
data!: TeamMembershipOutput[];
|
||||
data!: OrganizationMembershipOutput[];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { OrganizationMembershipOutput } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsNotEmptyObject, ValidateNested } from "class-validator";
|
||||
@@ -11,10 +11,10 @@ export class GetOrgMembership {
|
||||
status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS;
|
||||
|
||||
@ApiProperty({
|
||||
type: TeamMembershipOutput,
|
||||
type: OrganizationMembershipOutput,
|
||||
})
|
||||
@IsNotEmptyObject()
|
||||
@ValidateNested()
|
||||
@Type(() => TeamMembershipOutput)
|
||||
data!: TeamMembershipOutput;
|
||||
@Type(() => OrganizationMembershipOutput)
|
||||
data!: OrganizationMembershipOutput;
|
||||
}
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { ApiExtraModels, ApiProperty, getSchemaPath } from "@nestjs/swagger";
|
||||
import { Expose, Type } from "class-transformer";
|
||||
import { IsArray, IsNumber, IsOptional, IsString, ValidateNested } from "class-validator";
|
||||
|
||||
class BaseAttribute {
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
id!: string;
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
name!: string;
|
||||
}
|
||||
|
||||
export class TextAttribute extends BaseAttribute {
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
type!: "text";
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
option!: string;
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
optionId!: string;
|
||||
}
|
||||
|
||||
export class NumberAttribute extends BaseAttribute {
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
type!: "number";
|
||||
|
||||
@IsNumber()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
option!: number;
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
optionId!: string;
|
||||
}
|
||||
|
||||
export class SingleSelectAttribute extends BaseAttribute {
|
||||
@IsString()
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
type!: "singleSelect";
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
option!: string;
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
optionId!: string;
|
||||
}
|
||||
|
||||
class MultiSelectAttributeOption {
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
optionId!: string;
|
||||
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
option!: string;
|
||||
}
|
||||
|
||||
export class MultiSelectAttribute extends BaseAttribute {
|
||||
@IsString()
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
type!: "multiSelect";
|
||||
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
options!: MultiSelectAttributeOption[];
|
||||
}
|
||||
|
||||
export type OrgUserAttribute = TextAttribute | NumberAttribute | SingleSelectAttribute | MultiSelectAttribute;
|
||||
|
||||
@ApiExtraModels(BaseAttribute, TextAttribute, NumberAttribute, SingleSelectAttribute, MultiSelectAttribute)
|
||||
export class OrganizationMembershipOutput extends TeamMembershipOutput {
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Expose()
|
||||
@ApiProperty({
|
||||
required: true,
|
||||
oneOf: [
|
||||
{ $ref: getSchemaPath(TextAttribute) },
|
||||
{ $ref: getSchemaPath(NumberAttribute) },
|
||||
{ $ref: getSchemaPath(SingleSelectAttribute) },
|
||||
{ $ref: getSchemaPath(MultiSelectAttribute) },
|
||||
],
|
||||
type: "array",
|
||||
})
|
||||
@Type(() => Object)
|
||||
attributes!: OrgUserAttribute[];
|
||||
}
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
import { TeamMembershipOutput } from "@/modules/teams/memberships/outputs/team-membership.output";
|
||||
import { OrganizationMembershipOutput } from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsNotEmptyObject, ValidateNested } from "class-validator";
|
||||
@@ -11,10 +11,10 @@ export class UpdateOrgMembership {
|
||||
status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS;
|
||||
|
||||
@ApiProperty({
|
||||
type: TeamMembershipOutput,
|
||||
type: OrganizationMembershipOutput,
|
||||
})
|
||||
@IsNotEmptyObject()
|
||||
@ValidateNested()
|
||||
@Type(() => TeamMembershipOutput)
|
||||
data!: TeamMembershipOutput;
|
||||
@Type(() => OrganizationMembershipOutput)
|
||||
data!: OrganizationMembershipOutput;
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import { DbOrgMembership } from "@/modules/organizations/memberships/organizations-membership.repository";
|
||||
import {
|
||||
MultiSelectAttribute,
|
||||
NumberAttribute,
|
||||
OrganizationMembershipOutput,
|
||||
OrgUserAttribute,
|
||||
SingleSelectAttribute,
|
||||
TextAttribute,
|
||||
} from "@/modules/organizations/memberships/outputs/organization-membership.output";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { plainToClass } from "class-transformer";
|
||||
|
||||
import { groupMembershipAttributes } from "@calcom/platform-libraries";
|
||||
import type { GroupedAttribute } from "@calcom/platform-libraries";
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationsMembershipOutputService {
|
||||
getOrgMembershipsOutput(memberships: NonNullable<DbOrgMembership>[]) {
|
||||
return memberships.map((membership) => this.getOrgMembershipOutput(membership));
|
||||
}
|
||||
|
||||
getOrgMembershipOutput(organizationMembership: NonNullable<DbOrgMembership>) {
|
||||
const { AttributeToUser, ...orgMembership } = organizationMembership;
|
||||
|
||||
const groupedMembershipAttributes: GroupedAttribute[] = groupMembershipAttributes(AttributeToUser);
|
||||
const attributesOutput = this.getAttributesOutput(groupedMembershipAttributes);
|
||||
|
||||
return plainToClass(OrganizationMembershipOutput, { ...orgMembership, attributes: attributesOutput });
|
||||
}
|
||||
|
||||
private getAttributesOutput(attributes: GroupedAttribute[]): OrgUserAttribute[] {
|
||||
return attributes.map((attribute) => {
|
||||
switch (attribute.type) {
|
||||
case "TEXT":
|
||||
return this.getTextAttributeOutput(attribute);
|
||||
case "NUMBER":
|
||||
return this.getNumberAttributeOutput(attribute);
|
||||
case "SINGLE_SELECT":
|
||||
return this.getSingleSelectAttributeOutput(attribute);
|
||||
case "MULTI_SELECT":
|
||||
return this.getMultiSelectAttributeOutput(attribute);
|
||||
default:
|
||||
return this.getTextAttributeOutput(attribute);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getTextAttributeOutput(attribute: GroupedAttribute): TextAttribute {
|
||||
return {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
optionId: attribute.options[0].id,
|
||||
option: attribute.options[0].value,
|
||||
type: "text",
|
||||
};
|
||||
}
|
||||
|
||||
private getNumberAttributeOutput(attribute: GroupedAttribute): NumberAttribute {
|
||||
return {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
optionId: attribute.options[0].id,
|
||||
option: +attribute.options[0].value,
|
||||
type: "number",
|
||||
};
|
||||
}
|
||||
|
||||
private getSingleSelectAttributeOutput(attribute: GroupedAttribute): SingleSelectAttribute {
|
||||
return {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
optionId: attribute.options[0].id,
|
||||
option: attribute.options[0].value,
|
||||
type: "singleSelect",
|
||||
};
|
||||
}
|
||||
|
||||
private getMultiSelectAttributeOutput(attribute: GroupedAttribute): MultiSelectAttribute {
|
||||
return {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
options: attribute.options.map((option: GroupedAttribute["options"][number]) => ({
|
||||
optionId: option.id,
|
||||
option: option.value,
|
||||
})),
|
||||
type: "multiSelect",
|
||||
};
|
||||
}
|
||||
}
|
||||
+25
-8
@@ -1,19 +1,30 @@
|
||||
import { CreateOrgMembershipDto } from "@/modules/organizations/memberships/inputs/create-organization-membership.input";
|
||||
import { OrganizationsMembershipRepository } from "@/modules/organizations/memberships/organizations-membership.repository";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||
|
||||
import { UpdateOrgMembershipDto } from "../inputs/update-organization-membership.input";
|
||||
import { OrganizationsMembershipOutputService } from "./organizations-membership-output.service";
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationsMembershipService {
|
||||
constructor(private readonly organizationsMembershipRepository: OrganizationsMembershipRepository) {}
|
||||
constructor(
|
||||
private readonly organizationsMembershipRepository: OrganizationsMembershipRepository,
|
||||
private readonly organizationsMembershipOutputService: OrganizationsMembershipOutputService
|
||||
) {}
|
||||
|
||||
async getOrgMembership(organizationId: number, membershipId: number) {
|
||||
const membership = await this.organizationsMembershipRepository.findOrgMembership(
|
||||
organizationId,
|
||||
membershipId
|
||||
);
|
||||
return membership;
|
||||
|
||||
if (!membership) {
|
||||
throw new NotFoundException(
|
||||
`Membership with id ${membershipId} within organization id ${organizationId} not found`
|
||||
);
|
||||
}
|
||||
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipOutput(membership);
|
||||
}
|
||||
|
||||
async getOrgMembershipByUserId(organizationId: number, userId: number) {
|
||||
@@ -21,7 +32,13 @@ export class OrganizationsMembershipService {
|
||||
organizationId,
|
||||
userId
|
||||
);
|
||||
return membership;
|
||||
if (!membership) {
|
||||
throw new NotFoundException(
|
||||
`Membership for user with id ${userId} within organization id ${organizationId} not found`
|
||||
);
|
||||
}
|
||||
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipOutput(membership);
|
||||
}
|
||||
|
||||
async getPaginatedOrgMemberships(organizationId: number, skip = 0, take = 250) {
|
||||
@@ -30,7 +47,7 @@ export class OrganizationsMembershipService {
|
||||
skip,
|
||||
take
|
||||
);
|
||||
return memberships;
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipsOutput(memberships);
|
||||
}
|
||||
|
||||
async deleteOrgMembership(organizationId: number, membershipId: number) {
|
||||
@@ -38,7 +55,7 @@ export class OrganizationsMembershipService {
|
||||
organizationId,
|
||||
membershipId
|
||||
);
|
||||
return membership;
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipOutput(membership);
|
||||
}
|
||||
|
||||
async updateOrgMembership(organizationId: number, membershipId: number, data: UpdateOrgMembershipDto) {
|
||||
@@ -47,11 +64,11 @@ export class OrganizationsMembershipService {
|
||||
membershipId,
|
||||
data
|
||||
);
|
||||
return membership;
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipOutput(membership);
|
||||
}
|
||||
|
||||
async createOrgMembership(organizationId: number, data: CreateOrgMembershipDto) {
|
||||
const membership = await this.organizationsMembershipRepository.createOrgMembership(organizationId, data);
|
||||
return membership;
|
||||
return this.organizationsMembershipOutputService.getOrgMembershipOutput(membership);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import { OrganizationsRepository } from "@/modules/organizations/index/organizat
|
||||
import { OrganizationsService } from "@/modules/organizations/index/organizations.service";
|
||||
import { OrganizationsMembershipsController } from "@/modules/organizations/memberships/organizations-membership.controller";
|
||||
import { OrganizationsMembershipRepository } from "@/modules/organizations/memberships/organizations-membership.repository";
|
||||
import { OrganizationsMembershipOutputService } from "@/modules/organizations/memberships/services/organizations-membership-output.service";
|
||||
import { OrganizationsMembershipService } from "@/modules/organizations/memberships/services/organizations-membership.service";
|
||||
import { OrganizationsOrganizationsModule } from "@/modules/organizations/organizations/organizations-organizations.module";
|
||||
import { OrganizationsSchedulesController } from "@/modules/organizations/schedules/organizations-schedules.controller";
|
||||
@@ -98,6 +99,7 @@ import { Module } from "@nestjs/common";
|
||||
EmailService,
|
||||
OrganizationsMembershipRepository,
|
||||
OrganizationsMembershipService,
|
||||
OrganizationsMembershipOutputService,
|
||||
OrganizationsEventTypesService,
|
||||
InputOrganizationsEventTypesService,
|
||||
OutputOrganizationsEventTypesService,
|
||||
|
||||
+2
@@ -4,6 +4,7 @@ import { MembershipsModule } from "@/modules/memberships/memberships.module";
|
||||
import { MembershipsRepository } from "@/modules/memberships/memberships.repository";
|
||||
import { OrganizationsRepository } from "@/modules/organizations/index/organizations.repository";
|
||||
import { OrganizationsMembershipRepository } from "@/modules/organizations/memberships/organizations-membership.repository";
|
||||
import { OrganizationsMembershipOutputService } from "@/modules/organizations/memberships/services/organizations-membership-output.service";
|
||||
import { OrganizationsMembershipService } from "@/modules/organizations/memberships/services/organizations-membership.service";
|
||||
import { ManagedOrganizationsRepository } from "@/modules/organizations/organizations/managed-organizations.repository";
|
||||
import { OrganizationsOrganizationsController } from "@/modules/organizations/organizations/organizations-organizations.controller";
|
||||
@@ -23,6 +24,7 @@ import { Module } from "@nestjs/common";
|
||||
ManagedOrganizationsBillingService,
|
||||
OrganizationsRepository,
|
||||
OrganizationsMembershipService,
|
||||
OrganizationsMembershipOutputService,
|
||||
OrganizationsMembershipRepository,
|
||||
ManagedOrganizationsOutputService,
|
||||
],
|
||||
|
||||
+2
-1
@@ -54,7 +54,7 @@ export class OrganizationsTeamsBookingsController {
|
||||
@Param("orgId", ParseIntPipe) orgId: number,
|
||||
@GetUser() user: UserWithProfile
|
||||
): Promise<GetBookingsOutput_2024_08_13> {
|
||||
const bookings = await this.bookingsService.getBookings(
|
||||
const { bookings, pagination } = await this.bookingsService.getBookings(
|
||||
{ ...queryParams, teamId },
|
||||
{ email: user.email, id: user.id, orgId }
|
||||
);
|
||||
@@ -62,6 +62,7 @@ export class OrganizationsTeamsBookingsController {
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: bookings,
|
||||
pagination,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -40,7 +40,7 @@ export class OrganizationsUsersBookingsController {
|
||||
@Param("userId", ParseIntPipe) userId: number,
|
||||
@Query() query: GetBookingsInput_2024_08_13
|
||||
): Promise<GetBookingsOutput_2024_08_13> {
|
||||
const bookings = await this.organizationUsersBookingsService.getOrganizationUserBookings(
|
||||
const { bookings, pagination } = await this.organizationUsersBookingsService.getOrganizationUserBookings(
|
||||
orgId,
|
||||
userId,
|
||||
query
|
||||
@@ -49,6 +49,7 @@ export class OrganizationsUsersBookingsController {
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: bookings,
|
||||
pagination,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -29,6 +29,7 @@ import {
|
||||
RecurringBookingOutput_2024_08_13,
|
||||
GetBookingsOutput_2024_08_13,
|
||||
GetSeatedBookingOutput_2024_08_13,
|
||||
PaginationMetaDto,
|
||||
} from "@calcom/platform-types";
|
||||
import { PlatformOAuthClient, Team } from "@calcom/prisma/client";
|
||||
|
||||
@@ -373,17 +374,26 @@ describe("Organizations UsersBookings Endpoints 2024-08-13", () => {
|
||||
const responseBody: GetBookingsOutput_2024_08_13 = response.body;
|
||||
expect(responseBody.status).toEqual(SUCCESS_STATUS);
|
||||
expect(responseBody.data).toBeDefined();
|
||||
expect(responseBody.pagination).toBeDefined();
|
||||
const data: (
|
||||
| BookingOutput_2024_08_13
|
||||
| RecurringBookingOutput_2024_08_13
|
||||
| GetSeatedBookingOutput_2024_08_13
|
||||
)[] = responseBody.data;
|
||||
const pagination: PaginationMetaDto = responseBody.pagination;
|
||||
expect(data.length).toEqual(3);
|
||||
expect(data.find((booking) => booking.id === createdPersonalBooking.id)).toBeDefined();
|
||||
expect(data.find((booking) => booking.id === createdTeamBooking.id)).toBeDefined();
|
||||
expect(
|
||||
data.find((booking) => booking.id === createdPersonalBookingUsingUsername.id)
|
||||
).toBeDefined();
|
||||
expect(pagination.totalItems).toEqual(3);
|
||||
expect(pagination.remainingItems).toEqual(0);
|
||||
expect(pagination.hasNextPage).toEqual(false);
|
||||
expect(pagination.hasPreviousPage).toEqual(false);
|
||||
expect(pagination.itemsPerPage).toEqual(100);
|
||||
expect(pagination.totalPages).toEqual(1);
|
||||
expect(pagination.currentPage).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import { AppsRepository } from "@/modules/apps/apps.repository";
|
||||
import { CredentialsRepository } from "@/modules/credentials/credentials.repository";
|
||||
import { OrganizationsDelegationCredentialRepository } from "@/modules/organizations/delegation-credentials/organizations-delegation-credential.repository";
|
||||
import { OrganizationsMembershipRepository } from "@/modules/organizations/memberships/organizations-membership.repository";
|
||||
import { OrganizationsMembershipOutputService } from "@/modules/organizations/memberships/services/organizations-membership-output.service";
|
||||
import { OrganizationsMembershipService } from "@/modules/organizations/memberships/services/organizations-membership.service";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { SelectedCalendarsController } from "@/modules/selected-calendars/controllers/selected-calendars.controller";
|
||||
@@ -22,6 +23,7 @@ import { Module } from "@nestjs/common";
|
||||
CredentialsRepository,
|
||||
AppsRepository,
|
||||
OrganizationsMembershipService,
|
||||
OrganizationsMembershipOutputService,
|
||||
OrganizationsDelegationCredentialRepository,
|
||||
OrganizationsMembershipRepository,
|
||||
SelectedCalendarsService,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SlotsOutputService_2024_04_15 } from "@/modules/slots/slots-2024-04-15/services/slots-output.service";
|
||||
import type { RangeSlots, TimeSlots } from "@/modules/slots/slots-2024-04-15/services/slots-output.service";
|
||||
import { SlotsService_2024_04_15 } from "@/modules/slots/slots-2024-04-15/services/slots.service";
|
||||
import { Query, Body, Controller, Get, Delete, Post, Req, Res } from "@nestjs/common";
|
||||
import { Query, Body, Controller, Get, Delete, Post, Req, Res, BadRequestException } from "@nestjs/common";
|
||||
import { ApiExcludeController as DocsExcludeController } from "@nestjs/swagger";
|
||||
import { ApiTags as DocsTags, ApiCreatedResponse, ApiOkResponse, ApiOperation } from "@nestjs/swagger";
|
||||
import { Response as ExpressResponse, Request as ExpressRequest } from "express";
|
||||
@@ -157,7 +157,11 @@ export class SlotsController_2024_04_15 {
|
||||
@Query() query: GetAvailableSlotsInput_2024_04_15,
|
||||
@Req() req: ExpressRequest
|
||||
): Promise<ApiResponse<{ slots: TimeSlots["slots"] | RangeSlots["slots"] }>> {
|
||||
const isTeamEvent = await this.slotsService.checkIfIsTeamEvent(query.eventTypeId);
|
||||
try {
|
||||
const isTeamEvent =
|
||||
query.isTeamEvent === undefined
|
||||
? await this.slotsService.checkIfIsTeamEvent(query.eventTypeId)
|
||||
: query.isTeamEvent;
|
||||
const availableSlots = await getAvailableSlots({
|
||||
input: {
|
||||
...query,
|
||||
@@ -168,19 +172,29 @@ export class SlotsController_2024_04_15 {
|
||||
},
|
||||
});
|
||||
|
||||
const { slots } = await this.slotsOutputService.getOutputSlots(
|
||||
availableSlots,
|
||||
query.duration,
|
||||
query.eventTypeId,
|
||||
query.slotFormat,
|
||||
query.timeZone
|
||||
);
|
||||
const { slots } = await this.slotsOutputService.getOutputSlots(
|
||||
availableSlots,
|
||||
query.duration,
|
||||
query.eventTypeId,
|
||||
query.slotFormat,
|
||||
query.timeZone
|
||||
);
|
||||
|
||||
return {
|
||||
data: {
|
||||
slots,
|
||||
},
|
||||
status: SUCCESS_STATUS,
|
||||
};
|
||||
return {
|
||||
data: {
|
||||
slots,
|
||||
},
|
||||
status: SUCCESS_STATUS,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes("Invalid time range given")) {
|
||||
throw new BadRequestException(
|
||||
"Invalid time range given - check the 'startTime' and 'endTime' query parameters."
|
||||
);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ export class SlotsController_2024_09_04 {
|
||||
Optional parameters are:
|
||||
- timeZone: Time zone in which the available slots should be returned. Defaults to UTC.
|
||||
- duration: Only use for event types that allow multiple durations or for dynamic event types. If not passed for multiple duration event types defaults to default duration. For dynamic event types defaults to 30 aka each returned slot is 30 minutes long. So duration=60 means that returned slots will be each 60 minutes long.
|
||||
- slotFormat: Format of the slots. By default return is an object where each key is date and value is array of slots as string. If you want to get start and end of each slot use "range" as value.
|
||||
- format: Format of the slots. By default return is an object where each key is date and value is array of slots as string. If you want to get start and end of each slot use "range" as value.
|
||||
`,
|
||||
})
|
||||
@ApiQuery({
|
||||
@@ -99,7 +99,7 @@ export class SlotsController_2024_09_04 {
|
||||
example: "60",
|
||||
})
|
||||
@ApiQuery({
|
||||
name: "slotFormat",
|
||||
name: "format",
|
||||
required: false,
|
||||
description:
|
||||
"Format of slot times in response. Use 'range' to get start and end times. Use 'time' or omit this query parameter to get only start time.",
|
||||
|
||||
@@ -42,24 +42,33 @@ export class SlotsService_2024_09_04 {
|
||||
) {}
|
||||
|
||||
async getAvailableSlots(query: GetSlotsInput_2024_09_04) {
|
||||
const queryTransformed = await this.slotsInputService.transformGetSlotsQuery(query);
|
||||
try {
|
||||
const queryTransformed = await this.slotsInputService.transformGetSlotsQuery(query);
|
||||
const availableSlots: TimeSlots = await getAvailableSlots({
|
||||
input: {
|
||||
...queryTransformed,
|
||||
},
|
||||
ctx: {},
|
||||
});
|
||||
const formatted = await this.slotsOutputService.getAvailableSlots(
|
||||
availableSlots,
|
||||
queryTransformed.eventTypeId,
|
||||
queryTransformed.duration,
|
||||
query.format,
|
||||
queryTransformed.timeZone
|
||||
);
|
||||
|
||||
const availableSlots: TimeSlots = await getAvailableSlots({
|
||||
input: {
|
||||
...queryTransformed,
|
||||
},
|
||||
ctx: {},
|
||||
});
|
||||
|
||||
const formatted = await this.slotsOutputService.getAvailableSlots(
|
||||
availableSlots,
|
||||
queryTransformed.eventTypeId,
|
||||
queryTransformed.duration,
|
||||
query.format,
|
||||
queryTransformed.timeZone
|
||||
);
|
||||
|
||||
return formatted;
|
||||
return formatted;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes("Invalid time range given")) {
|
||||
throw new BadRequestException(
|
||||
"Invalid time range given - check the 'start' and 'end' query parameters."
|
||||
);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async reserveSlot(input: ReserveSlotInput_2024_09_04, authUserId?: number) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EventTypesModule_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.module";
|
||||
import { ConferencingRepository } from "@/modules/conferencing/repositories/conferencing.repository";
|
||||
import { MembershipsModule } from "@/modules/memberships/memberships.module";
|
||||
import { OrganizationsConferencingModule } from "@/modules/organizations/conferencing/organizations-conferencing.module";
|
||||
import { OutputTeamEventTypesResponsePipe } from "@/modules/organizations/event-types/pipes/team-event-types-response.transformer";
|
||||
@@ -31,6 +32,7 @@ import { Module } from "@nestjs/common";
|
||||
OrganizationsTeamsRepository,
|
||||
OutputTeamEventTypesResponsePipe,
|
||||
OutputOrganizationsEventTypesService,
|
||||
ConferencingRepository,
|
||||
],
|
||||
exports: [TeamsEventTypesRepository, TeamsEventTypesService],
|
||||
controllers: [TeamsEventTypesController],
|
||||
|
||||
@@ -317,4 +317,73 @@ export class UsersRepository {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getOrgsManagedUserEmailsBySubscriptionId(subscriptionId: string) {
|
||||
return await this.dbRead.prisma.user.findMany({
|
||||
distinct: ["email"],
|
||||
where: {
|
||||
isPlatformManaged: true,
|
||||
profiles: {
|
||||
some: {
|
||||
organization: {
|
||||
platformBilling: {
|
||||
subscriptionId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getActiveManagedUsersAsHost(subscriptionId: string, startTime: Date, endTime: Date) {
|
||||
return await this.dbRead.prisma.user.findMany({
|
||||
distinct: ["email"],
|
||||
where: {
|
||||
isPlatformManaged: true,
|
||||
profiles: {
|
||||
some: {
|
||||
organization: {
|
||||
platformBilling: {
|
||||
subscriptionId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
bookings: {
|
||||
some: {
|
||||
userId: { not: null },
|
||||
startTime: {
|
||||
gte: startTime,
|
||||
lte: endTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getActiveManagedUsersAsAttendee(managedUsersEmails: string[], startTime: Date, endTime: Date) {
|
||||
return await this.dbRead.prisma.attendee.findMany({
|
||||
distinct: ["email"],
|
||||
where: {
|
||||
email: { in: managedUsersEmails },
|
||||
booking: {
|
||||
startTime: {
|
||||
gte: startTime,
|
||||
lte: endTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1689,6 +1689,7 @@
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"default": 100,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -1699,6 +1700,7 @@
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -5603,6 +5605,7 @@
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"default": 100,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -5613,6 +5616,7 @@
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
@@ -6978,6 +6982,7 @@
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"default": 100,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -6988,6 +6993,7 @@
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -10500,7 +10506,7 @@
|
||||
"get": {
|
||||
"operationId": "SlotsController_2024_09_04_getAvailableSlots",
|
||||
"summary": "Find out when is an event type ready to be booked.",
|
||||
"description": "\n There are 4 ways to get available slots for event type of an individual user:\n\n 1. By event type id. Event type id can be of user and team event types. Example '/v2/slots?eventTypeId=10&start=2050-09-05&end=2050-09-06&timeZone=Europe/Rome'\n\n 2. By event type slug + username. Example '/v2/slots?eventTypeSlug=intro&username=bob&start=2050-09-05&end=2050-09-06'\n\n 3. By event type slug + username + organization slug when searching within an organization. Example '/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&username=bob&start=2050-09-05&end=2050-09-06'\n\n 4. By usernames only (used for dynamic event type - there is no specific event but you want to know when 2 or more people are available). Example '/v2/slots?usernames=alice,bob&username=bob&organizationSlug=org-slug&start=2050-09-05&end=2050-09-06'. As you see you also need to provide the slug of the organization to which each user in the 'usernames' array belongs.\n\n And 3 ways to get available slots for team event type:\n\n 1. By team event type id. Example '/v2/slots?eventTypeId=10&start=2050-09-05&end=2050-09-06&timeZone=Europe/Rome'\n\n 2. By team event type slug + team slug. Example '/v2/slots?eventTypeSlug=intro&teamSlug=team-slug&start=2050-09-05&end=2050-09-06'\n\n 3. By team event type slug + team slug + organization slug when searching within an organization. Example '/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&teamSlug=team-slug&start=2050-09-05&end=2050-09-06'\n\n All of them require \"start\" and \"end\" query parameters which define the time range for which available slots should be checked.\n Optional parameters are:\n - timeZone: Time zone in which the available slots should be returned. Defaults to UTC.\n - duration: Only use for event types that allow multiple durations or for dynamic event types. If not passed for multiple duration event types defaults to default duration. For dynamic event types defaults to 30 aka each returned slot is 30 minutes long. So duration=60 means that returned slots will be each 60 minutes long.\n - slotFormat: Format of the slots. By default return is an object where each key is date and value is array of slots as string. If you want to get start and end of each slot use \"range\" as value.\n ",
|
||||
"description": "\n There are 4 ways to get available slots for event type of an individual user:\n\n 1. By event type id. Event type id can be of user and team event types. Example '/v2/slots?eventTypeId=10&start=2050-09-05&end=2050-09-06&timeZone=Europe/Rome'\n\n 2. By event type slug + username. Example '/v2/slots?eventTypeSlug=intro&username=bob&start=2050-09-05&end=2050-09-06'\n\n 3. By event type slug + username + organization slug when searching within an organization. Example '/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&username=bob&start=2050-09-05&end=2050-09-06'\n\n 4. By usernames only (used for dynamic event type - there is no specific event but you want to know when 2 or more people are available). Example '/v2/slots?usernames=alice,bob&username=bob&organizationSlug=org-slug&start=2050-09-05&end=2050-09-06'. As you see you also need to provide the slug of the organization to which each user in the 'usernames' array belongs.\n\n And 3 ways to get available slots for team event type:\n\n 1. By team event type id. Example '/v2/slots?eventTypeId=10&start=2050-09-05&end=2050-09-06&timeZone=Europe/Rome'\n\n 2. By team event type slug + team slug. Example '/v2/slots?eventTypeSlug=intro&teamSlug=team-slug&start=2050-09-05&end=2050-09-06'\n\n 3. By team event type slug + team slug + organization slug when searching within an organization. Example '/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&teamSlug=team-slug&start=2050-09-05&end=2050-09-06'\n\n All of them require \"start\" and \"end\" query parameters which define the time range for which available slots should be checked.\n Optional parameters are:\n - timeZone: Time zone in which the available slots should be returned. Defaults to UTC.\n - duration: Only use for event types that allow multiple durations or for dynamic event types. If not passed for multiple duration event types defaults to default duration. For dynamic event types defaults to 30 aka each returned slot is 30 minutes long. So duration=60 means that returned slots will be each 60 minutes long.\n - format: Format of the slots. By default return is an object where each key is date and value is array of slots as string. If you want to get start and end of each slot use \"range\" as value.\n ",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "cal-api-version",
|
||||
@@ -10577,7 +10583,7 @@
|
||||
"schema": {}
|
||||
},
|
||||
{
|
||||
"name": "slotFormat",
|
||||
"name": "format",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Format of slot times in response. Use 'range' to get start and end times. Use 'time' or omit this query parameter to get only start time.",
|
||||
@@ -17098,154 +17104,6 @@
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"ConferencingAppsOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Id of the conferencing app credentials"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "google_video",
|
||||
"description": "Type of conferencing app"
|
||||
},
|
||||
"userId": {
|
||||
"type": "number",
|
||||
"description": "Id of the user associated to the conferencing app"
|
||||
},
|
||||
"invalid": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"example": true,
|
||||
"description": "Whether if the connection is working or not."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type",
|
||||
"userId"
|
||||
]
|
||||
},
|
||||
"ConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"GetConferencingAppsOauthUrlResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"ConferencingAppsOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"SetDefaultConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"DefaultConferencingAppsOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"appSlug": {
|
||||
"type": "string"
|
||||
},
|
||||
"appLink": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"GetDefaultConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"DisconnectConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"OrgTeamOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -18260,6 +18118,143 @@
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"BaseAttribute": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"TextAttribute": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"option": {
|
||||
"type": "string"
|
||||
},
|
||||
"optionId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"option",
|
||||
"optionId"
|
||||
]
|
||||
},
|
||||
"NumberAttribute": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"option": {
|
||||
"type": "number"
|
||||
},
|
||||
"optionId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"option",
|
||||
"optionId"
|
||||
]
|
||||
},
|
||||
"SingleSelectAttribute": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"option": {
|
||||
"type": "string"
|
||||
},
|
||||
"optionId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"option",
|
||||
"optionId"
|
||||
]
|
||||
},
|
||||
"MultiSelectAttributeOption": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"optionId": {
|
||||
"type": "string"
|
||||
},
|
||||
"option": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"optionId",
|
||||
"option"
|
||||
]
|
||||
},
|
||||
"MultiSelectAttribute": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/MultiSelectAttributeOption"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"options"
|
||||
]
|
||||
},
|
||||
"MembershipUserOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -18289,7 +18284,7 @@
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"TeamMembershipOutput": {
|
||||
"OrganizationMembershipOutput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -18317,6 +18312,25 @@
|
||||
},
|
||||
"user": {
|
||||
"$ref": "#/components/schemas/MembershipUserOutputDto"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/TextAttribute"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/NumberAttribute"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/SingleSelectAttribute"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/MultiSelectAttribute"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -18325,7 +18339,8 @@
|
||||
"teamId",
|
||||
"accepted",
|
||||
"role",
|
||||
"user"
|
||||
"user",
|
||||
"attributes"
|
||||
]
|
||||
},
|
||||
"GetAllOrgMemberships": {
|
||||
@@ -18340,7 +18355,7 @@
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/TeamMembershipOutput"
|
||||
"$ref": "#/components/schemas/OrganizationMembershipOutput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -18390,7 +18405,7 @@
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/TeamMembershipOutput"
|
||||
"$ref": "#/components/schemas/OrganizationMembershipOutput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -18410,7 +18425,7 @@
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/TeamMembershipOutput"
|
||||
"$ref": "#/components/schemas/OrganizationMembershipOutput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -18430,7 +18445,7 @@
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/TeamMembershipOutput"
|
||||
"$ref": "#/components/schemas/OrganizationMembershipOutput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -18469,7 +18484,7 @@
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/TeamMembershipOutput"
|
||||
"$ref": "#/components/schemas/OrganizationMembershipOutput"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -19692,6 +19707,45 @@
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"TeamMembershipOutput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number"
|
||||
},
|
||||
"userId": {
|
||||
"type": "number"
|
||||
},
|
||||
"teamId": {
|
||||
"type": "number"
|
||||
},
|
||||
"accepted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"role": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"MEMBER",
|
||||
"OWNER",
|
||||
"ADMIN"
|
||||
]
|
||||
},
|
||||
"disableImpersonation": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"user": {
|
||||
"$ref": "#/components/schemas/MembershipUserOutputDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"userId",
|
||||
"teamId",
|
||||
"accepted",
|
||||
"role",
|
||||
"user"
|
||||
]
|
||||
},
|
||||
"OrgTeamMembershipsOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -20941,6 +20995,154 @@
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"ConferencingAppsOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Id of the conferencing app credentials"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "google_video",
|
||||
"description": "Type of conferencing app"
|
||||
},
|
||||
"userId": {
|
||||
"type": "number",
|
||||
"description": "Id of the user associated to the conferencing app"
|
||||
},
|
||||
"invalid": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"example": true,
|
||||
"description": "Whether if the connection is working or not."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type",
|
||||
"userId"
|
||||
]
|
||||
},
|
||||
"ConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"GetConferencingAppsOauthUrlResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"ConferencingAppsOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"SetDefaultConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"DefaultConferencingAppsOutputDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"appSlug": {
|
||||
"type": "string"
|
||||
},
|
||||
"appLink": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"GetDefaultConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"DisconnectConferencingAppOutputResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"example": "success",
|
||||
"enum": [
|
||||
"success",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"GoogleServiceAccountKeyInput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -23941,6 +24143,60 @@
|
||||
"data"
|
||||
]
|
||||
},
|
||||
"PaginationMetaDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"totalItems": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"description": "The total number of items available across all pages, matching the query criteria.",
|
||||
"example": 123
|
||||
},
|
||||
"remainingItems": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"description": "The number of items remaining to be fetched *after* the current page. Calculated as: `totalItems - (skip + itemsPerPage)`.",
|
||||
"example": 103
|
||||
},
|
||||
"itemsPerPage": {
|
||||
"type": "number",
|
||||
"minimum": 1,
|
||||
"description": "The maximum number of items requested per page.",
|
||||
"example": 10
|
||||
},
|
||||
"currentPage": {
|
||||
"type": "number",
|
||||
"minimum": 1,
|
||||
"description": "The current page number being returned.",
|
||||
"example": 2
|
||||
},
|
||||
"totalPages": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"description": "The total number of pages available.",
|
||||
"example": 13
|
||||
},
|
||||
"hasNextPage": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates if there is a subsequent page available after the current one.",
|
||||
"example": true
|
||||
},
|
||||
"hasPreviousPage": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates if there is a preceding page available before the current one.",
|
||||
"example": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"totalItems",
|
||||
"remainingItems",
|
||||
"itemsPerPage",
|
||||
"currentPage",
|
||||
"totalPages",
|
||||
"hasNextPage",
|
||||
"hasPreviousPage"
|
||||
]
|
||||
},
|
||||
"GetBookingsOutput_2024_08_13": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -23972,13 +24228,17 @@
|
||||
},
|
||||
"description": "Array of booking data, which can contain either BookingOutput objects or RecurringBookingOutput objects"
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/components/schemas/PaginationMetaDto"
|
||||
},
|
||||
"error": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
"data",
|
||||
"pagination"
|
||||
]
|
||||
},
|
||||
"RescheduleBookingInput_2024_08_13": {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { TestingModule } from "@nestjs/testing";
|
||||
|
||||
export class WorkflowReminderRepositoryFixture {
|
||||
private prismaReadClient: PrismaReadService["prisma"];
|
||||
private prismaWriteClient: PrismaWriteService["prisma"];
|
||||
|
||||
constructor(private readonly module: TestingModule) {
|
||||
this.prismaReadClient = module.get(PrismaReadService).prisma;
|
||||
this.prismaWriteClient = module.get(PrismaWriteService).prisma;
|
||||
}
|
||||
|
||||
async getByBookingUid(uid: string) {
|
||||
return this.prismaReadClient.workflowReminder.findFirst({ where: { bookingUid: uid } });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { TestingModule } from "@nestjs/testing";
|
||||
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
export class WorkflowRepositoryFixture {
|
||||
private prismaReadClient: PrismaReadService["prisma"];
|
||||
private prismaWriteClient: PrismaWriteService["prisma"];
|
||||
|
||||
constructor(private readonly module: TestingModule) {
|
||||
this.prismaReadClient = module.get(PrismaReadService).prisma;
|
||||
this.prismaWriteClient = module.get(PrismaWriteService).prisma;
|
||||
}
|
||||
|
||||
async create(data: Prisma.WorkflowCreateInput) {
|
||||
return this.prismaWriteClient.workflow.create({ data });
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
return this.prismaWriteClient.workflow.delete({ where: { id } });
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ Buttons can be grouped together using the ButtonGroup component. The ButtonGroup
|
||||
|
||||
### Button Group Sizes
|
||||
|
||||
#### Seperated
|
||||
#### Separated
|
||||
|
||||
<ButtonGroupSizes/>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export const SizesExample: React.FC = () => (
|
||||
<div className="space-y-4 md:w-80">
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-emphasis text-sm">Default Height</h3>
|
||||
<TextAreaField name="deafult" placeholder="Default height textarea..." />
|
||||
<TextAreaField name="default" placeholder="Default height textarea..." />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
||||
+3
-1
@@ -69,4 +69,6 @@ public/embed
|
||||
# Copied app-store images
|
||||
public/app-store
|
||||
|
||||
certificates
|
||||
certificates
|
||||
# Sentry Config File
|
||||
.env.sentry-build-plugin
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { NextApiResponse } from "next";
|
||||
import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
|
||||
import { parseRequestData } from "app/api/parseRequestData";
|
||||
import { NextResponse, type NextRequest } from "next/server";
|
||||
|
||||
import calcomSignupHandler from "@calcom/feature-auth/signup/handlers/calcomHandler";
|
||||
import selfHostedSignupHandler from "@calcom/feature-auth/signup/handlers/selfHostedHandler";
|
||||
import { type RequestWithUsernameStatus } from "@calcom/features/auth/signup/username";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { IS_PREMIUM_USERNAME_ENABLED } from "@calcom/lib/constants";
|
||||
import getIP from "@calcom/lib/getIP";
|
||||
@@ -11,12 +12,12 @@ import logger from "@calcom/lib/logger";
|
||||
import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken";
|
||||
import { signupSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
async function ensureSignupIsEnabled(req: RequestWithUsernameStatus) {
|
||||
async function ensureSignupIsEnabled(body: Record<string, string>) {
|
||||
const { token } = signupSchema
|
||||
.pick({
|
||||
token: true,
|
||||
})
|
||||
.parse(req.body);
|
||||
.parse(body);
|
||||
|
||||
// Still allow signups if there is a team invite
|
||||
if (token) return;
|
||||
@@ -32,26 +33,17 @@ async function ensureSignupIsEnabled(req: RequestWithUsernameStatus) {
|
||||
}
|
||||
}
|
||||
|
||||
function ensureReqIsPost(req: RequestWithUsernameStatus) {
|
||||
if (req.method !== "POST") {
|
||||
throw new HttpError({
|
||||
statusCode: 405,
|
||||
message: "Method not allowed",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default async function handler(req: RequestWithUsernameStatus, res: NextApiResponse) {
|
||||
async function handler(req: NextRequest) {
|
||||
const remoteIp = getIP(req);
|
||||
// Use a try catch instead of returning res every time
|
||||
try {
|
||||
const body = await parseRequestData(req);
|
||||
await checkCfTurnstileToken({
|
||||
token: req.headers["cf-access-token"] as string,
|
||||
token: req.headers.get("cf-access-token") as string,
|
||||
remoteIp,
|
||||
});
|
||||
|
||||
ensureReqIsPost(req);
|
||||
await ensureSignupIsEnabled(req);
|
||||
await ensureSignupIsEnabled(body);
|
||||
|
||||
/**
|
||||
* Im not sure its worth merging these two handlers. They are different enough to be separate.
|
||||
@@ -61,15 +53,17 @@ export default async function handler(req: RequestWithUsernameStatus, res: NextA
|
||||
* @zomars: We need to be able to test this with E2E. They way it's done RN it will never run on CI.
|
||||
*/
|
||||
if (IS_PREMIUM_USERNAME_ENABLED) {
|
||||
return await calcomSignupHandler(req, res);
|
||||
return await calcomSignupHandler(body);
|
||||
}
|
||||
|
||||
return await selfHostedSignupHandler(req, res);
|
||||
return await selfHostedSignupHandler(body);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpError) {
|
||||
return res.status(e.statusCode).json({ message: e.message });
|
||||
return NextResponse.json({ message: e.message }, { status: e.statusCode });
|
||||
}
|
||||
logger.error(e);
|
||||
return res.status(500).json({ message: "Internal server error" });
|
||||
return NextResponse.json({ message: "Internal server error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export const POST = defaultResponderForAppDir(handler);
|
||||
@@ -5,7 +5,8 @@ import { NextResponse } from "next/server";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendOrganizerRequestReminderEmail } from "@calcom/emails";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
|
||||
import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
|
||||
import { BookingStatus, ReminderType } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import * as twilio from "@calcom/features/ee/workflows/lib/reminders/providers/twilioProvider";
|
||||
import { IS_SMS_CREDITS_ENABLED } from "@calcom/lib/constants";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { CreditType } from "@calcom/prisma/enums";
|
||||
|
||||
async function postHandler(req: NextRequest) {
|
||||
const apiKey = req.headers.get("authorization") || req.nextUrl.searchParams.get("apiKey");
|
||||
|
||||
if (process.env.CRON_API_KEY !== apiKey) {
|
||||
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!IS_SMS_CREDITS_ENABLED) {
|
||||
return NextResponse.json({ ok: true, message: "SMS credits not enabled" });
|
||||
}
|
||||
|
||||
const smsLogsWithoutPrice = await prisma.creditExpenseLog.findMany({
|
||||
where: {
|
||||
credits: null,
|
||||
smsSid: {
|
||||
not: null,
|
||||
},
|
||||
date: {
|
||||
gte: dayjs().subtract(1, "hour").toDate(),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
smsSid: true,
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
let pricesUpdated = 0;
|
||||
const { CreditService } = await import("@calcom/features/ee/billing/credit-service");
|
||||
|
||||
const creditService = new CreditService();
|
||||
|
||||
await Promise.allSettled(
|
||||
smsLogsWithoutPrice.map(async (log) => {
|
||||
if (!log.smsSid) return;
|
||||
|
||||
try {
|
||||
const price = await twilio.getPriceForSMS(log.smsSid);
|
||||
const credits = price ? creditService.calculateCreditsFromPrice(price) : null;
|
||||
if (!credits) return;
|
||||
|
||||
const updatedLog = await prisma.creditExpenseLog.update({
|
||||
where: { id: log.id },
|
||||
data: { credits },
|
||||
select: {
|
||||
creditBalance: {
|
||||
select: {
|
||||
id: true,
|
||||
additionalCredits: true,
|
||||
teamId: true,
|
||||
userId: true,
|
||||
},
|
||||
},
|
||||
creditType: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (updatedLog.creditType === CreditType.ADDITIONAL) {
|
||||
const decrementValue =
|
||||
credits <= updatedLog.creditBalance.additionalCredits
|
||||
? credits
|
||||
: updatedLog.creditBalance.additionalCredits;
|
||||
|
||||
await prisma.creditBalance.update({
|
||||
where: { id: updatedLog.creditBalance.id },
|
||||
data: {
|
||||
additionalCredits: {
|
||||
decrement: decrementValue,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!updatedLog.creditBalance.teamId && !updatedLog.creditBalance.userId) {
|
||||
logger.error(`teamId or userId missing for expense log ${log.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const availableCredits = await creditService.getAllCredits({
|
||||
teamId: updatedLog.creditBalance.teamId,
|
||||
userId: updatedLog.creditBalance.userId,
|
||||
});
|
||||
|
||||
const remainingMonthlyCredits = Math.max(0, availableCredits.totalRemainingMonthlyCredits);
|
||||
|
||||
await creditService.handleLowCreditBalance({
|
||||
userId: updatedLog.creditBalance.userId,
|
||||
teamId: updatedLog.creditBalance.teamId,
|
||||
remainingCredits: remainingMonthlyCredits + availableCredits.additionalCredits,
|
||||
});
|
||||
|
||||
pricesUpdated++;
|
||||
} catch (err) {
|
||||
logger.error(`Failed to process SMS log ${log.smsSid}`, err);
|
||||
await prisma.creditExpenseLog.update({
|
||||
where: { id: log.id },
|
||||
data: { credits: 0 },
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return NextResponse.json({ ok: true, pricesUpdated });
|
||||
}
|
||||
|
||||
export const POST = defaultResponderForAppDir(postHandler);
|
||||
@@ -1,8 +1,14 @@
|
||||
/**
|
||||
* @description This route is used to create and delete Credential records for all members of an organization that has delegation credentials enabled.
|
||||
*
|
||||
* It also deletes Credential records for all members of an organization that has delegation credentials disabled.
|
||||
*/
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { CredentialRepository } from "@calcom/lib/server/repository/credential";
|
||||
import { DelegationCredentialRepository } from "@calcom/lib/server/repository/delegationCredential";
|
||||
|
||||
@@ -37,7 +43,7 @@ async function handleCreateCredentials() {
|
||||
log.info(
|
||||
`Skipping credential creation for workspace platform ${workspacePlatform.slug} - only google is supported`
|
||||
);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We can't know by looking at a Credential record in DB, if it has access to the `user.email` calendar in Google Calendar.
|
||||
@@ -50,15 +56,15 @@ async function handleCreateCredentials() {
|
||||
});
|
||||
|
||||
const existingCredentialUserIds = new Set(existingCredentials.map((cred) => cred.userId));
|
||||
|
||||
const membersNeedingCredentials = organization.delegatedMembers.filter(
|
||||
const delegatedMembers = organization.delegatedMembers;
|
||||
const membersNeedingCredentials = delegatedMembers.filter(
|
||||
(member) => !existingCredentialUserIds.has(member.userId)
|
||||
);
|
||||
|
||||
const toProcessMembers = membersNeedingCredentials.slice(0, batchSizeToCreateCredentials);
|
||||
|
||||
log.info(
|
||||
`Creating credentials for ${toProcessMembers.length} members in organization ${organization.id}`
|
||||
`Creating credentials for ${toProcessMembers.length} members out of ${delegatedMembers.length} delegated members in organization ${organization.id}`
|
||||
);
|
||||
|
||||
const credentialCreationPromises = toProcessMembers.map(async (member) => {
|
||||
@@ -75,18 +81,24 @@ async function handleCreateCredentials() {
|
||||
});
|
||||
log.info(`Created credential for member ${member.userId}`);
|
||||
} catch (error) {
|
||||
log.error(`Error creating credential for member ${member.userId}:`, error);
|
||||
log.error(`Error creating credential for member ${member.userId}:`, safeStringify(error));
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
const results = await Promise.allSettled(credentialCreationPromises);
|
||||
const successCount = results.filter((r) => r.status === "fulfilled").length;
|
||||
const failureCount = results.filter((r) => r.status === "rejected").length;
|
||||
|
||||
log.info(
|
||||
`Created ${successCount} credentials for delegationCredentialId: ${delegationCredential.id} and ${failureCount} failures`
|
||||
);
|
||||
totalSuccess += successCount;
|
||||
totalFailures += failureCount;
|
||||
}
|
||||
|
||||
log.info(
|
||||
`Completed creating credentials for all delegation credentials. Total Success: ${totalSuccess}, Total Failures: ${totalFailures}`
|
||||
);
|
||||
|
||||
return {
|
||||
executedAt: new Date().toISOString(),
|
||||
success: totalSuccess,
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* @description This route is used to create SelectedCalendar records based on Credential records corresponding to Delegation Credentials
|
||||
*
|
||||
* It works in conjunction with `/api/cron/credentials` route(which creates the Credential records for all the members of an organization that has delegation credentials enabled)
|
||||
*/
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -31,8 +36,10 @@ async function handleCreateSelectedCalendars() {
|
||||
});
|
||||
|
||||
if (!allDelegationUserCredentials.length) {
|
||||
const message = "No delegation credentials found";
|
||||
log.info(message);
|
||||
return {
|
||||
message: "No delegation credentials found",
|
||||
message,
|
||||
success: 0,
|
||||
failures: 0,
|
||||
};
|
||||
@@ -153,17 +160,19 @@ async function handleCreateSelectedCalendars() {
|
||||
);
|
||||
const successCount = results.filter((r) => r.status === "fulfilled").length;
|
||||
const failureCount = results.filter((r) => r.status === "rejected").length;
|
||||
|
||||
log.info(
|
||||
`Processed ${successCount} selected calendars for delegationCredentialId: ${delegationCredentialId} and ${failureCount} failures`
|
||||
);
|
||||
totalSuccess += successCount;
|
||||
totalFailures += failureCount;
|
||||
}
|
||||
|
||||
log.info(
|
||||
`Completed processing all selected calendars. Total Success: ${totalSuccess}, Total Failures: ${totalFailures}`
|
||||
`Completed creating selected calendars for all delegation credentials. Total Success: ${totalSuccess}, Total Failures: ${totalFailures}`
|
||||
);
|
||||
|
||||
return {
|
||||
message: "All selected calendars processed",
|
||||
message: "All selected calendars created",
|
||||
executedAt: new Date().toISOString(),
|
||||
success: totalSuccess,
|
||||
failures: totalFailures,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
|
||||
import { NextResponse } from "next/server";
|
||||
import * as pjson from "package.json";
|
||||
import packageJson from "package.json";
|
||||
|
||||
async function getHandler() {
|
||||
return NextResponse.json({ version: pjson.version });
|
||||
return NextResponse.json({ version: packageJson.version });
|
||||
}
|
||||
|
||||
export const GET = defaultResponderForAppDir(getHandler);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { type NextPage } from "next";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import CustomError from "./error";
|
||||
import type { ErrorProps } from "./error";
|
||||
|
||||
export const GlobalError: NextPage<ErrorProps> = (props) => {
|
||||
useEffect(() => {
|
||||
Sentry.captureException(props.error);
|
||||
}, [props.error]);
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
|
||||
@@ -7,7 +7,6 @@ import React from "react";
|
||||
import { getLocale } from "@calcom/features/auth/lib/getLocale";
|
||||
import { loadTranslations } from "@calcom/lib/server/i18n";
|
||||
import { IconSprites } from "@calcom/ui/components/icon";
|
||||
import { NotificationSoundHandler } from "@calcom/web/components/notification-sound-handler";
|
||||
|
||||
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
@@ -152,13 +151,11 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
||||
]}
|
||||
/>
|
||||
|
||||
<Providers>
|
||||
<Providers isEmbed={isEmbed}>
|
||||
<AppRouterI18nProvider translations={translations} locale={locale} ns={ns}>
|
||||
{children}
|
||||
</AppRouterI18nProvider>
|
||||
</Providers>
|
||||
{!isEmbed && <NotificationSoundHandler />}
|
||||
<NotificationSoundHandler />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -5,20 +5,23 @@ import { SessionProvider } from "next-auth/react";
|
||||
import CacheProvider from "react-inlinesvg/provider";
|
||||
|
||||
import { WebPushProvider } from "@calcom/features/notifications/WebPushContext";
|
||||
import { NotificationSoundHandler } from "@calcom/web/components/notification-sound-handler";
|
||||
|
||||
import useIsBookingPage from "@lib/hooks/useIsBookingPage";
|
||||
import PlainChat from "@lib/plain/dynamicProvider";
|
||||
|
||||
type ProvidersProps = {
|
||||
isEmbed: boolean;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export function Providers({ children }: ProvidersProps) {
|
||||
export function Providers({ isEmbed, children }: ProvidersProps) {
|
||||
const isBookingPage = useIsBookingPage();
|
||||
|
||||
return (
|
||||
<SessionProvider>
|
||||
<TrpcProvider>
|
||||
{!isBookingPage ? <PlainChat /> : null}
|
||||
{!isEmbed && !isBookingPage && <NotificationSoundHandler />}
|
||||
{/* @ts-expect-error FIXME remove this comment when upgrading typescript to v5 */}
|
||||
<CacheProvider>
|
||||
<WebPushProvider>{children}</WebPushProvider>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { Schedule } from "@calcom/features/schedules";
|
||||
import Schedule from "@calcom/features/schedules/components/Schedule";
|
||||
import { DEFAULT_SCHEDULE } from "@calcom/lib/availability";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// This file configures the initialization of Sentry on the client.
|
||||
// The added config here will be used whenever a users loads a page in their browser.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
|
||||
sampleRate: parseFloat(process.env.SENTRY_SAMPLE_RATE ?? "1.0") || 1.0,
|
||||
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
|
||||
tracesSampleRate: parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE ?? "0.0") || 0.0,
|
||||
|
||||
// Define how likely Replay events are sampled.
|
||||
// This sets the sample rate to be 10%. You may want this to be 100% while
|
||||
// in development and sample at a lower rate in production
|
||||
// replaysSessionSampleRate: parseFloat(process.env.SENTRY_REPLAYS_SESSION_SAMPLE_RATE ?? "0.0") || 0.0,
|
||||
|
||||
// Define how likely Replay events are sampled when an error occurs.
|
||||
// replaysOnErrorSampleRate: parseFloat(process.env.SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE ?? "0.0") || 0.0,
|
||||
|
||||
// Setting this option to true will print useful information to the console while you're setting up Sentry.
|
||||
debug: !!process.env.SENTRY_DEBUG,
|
||||
beforeSend(event) {
|
||||
event.tags = {
|
||||
...event.tags,
|
||||
errorSource: "client",
|
||||
};
|
||||
return event;
|
||||
},
|
||||
});
|
||||
|
||||
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
export async function register() {
|
||||
if (process.env.NEXT_PUBLIC_SENTRY_DSN && process.env.NEXT_RUNTIME === "nodejs") {
|
||||
await import("./sentry.server.config");
|
||||
@@ -7,3 +9,5 @@ export async function register() {
|
||||
await import("./sentry.edge.config");
|
||||
}
|
||||
}
|
||||
|
||||
export const onRequestError = Sentry.captureRequestError;
|
||||
|
||||
@@ -13,7 +13,7 @@ const enum ThemeSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique indentifier that remains same as long as we land on the public page for same entity like event-type/routing-form/dynamic-group-booking etc
|
||||
* Returns a unique identifier that remains the same as long as we land on the public page for the same entity like event-type/routing-form/dynamic-group-booking etc
|
||||
* The theme stays same for same identifier.
|
||||
*/
|
||||
export function getUniqueIdentifierForBookingPage({ pathname }: { pathname: string }) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
|
||||
import { getBookingForReschedule } from "@calcom/features/bookings/lib/get-booking";
|
||||
import { getSlugOrRequestedSlug, orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { getOrganizationSEOSettings } from "@calcom/features/ee/organizations/lib/orgSettings";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import prisma from "@calcom/prisma";
|
||||
@@ -113,8 +114,12 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||
const organizationSettings = getOrganizationSEOSettings(team);
|
||||
const allowSEOIndexing = organizationSettings?.allowSEOIndexing ?? false;
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const useApiV2 = await featureRepo.checkIfTeamHasFeature(team.id, "use-api-v2-for-team-slots");
|
||||
|
||||
return {
|
||||
props: {
|
||||
useApiV2,
|
||||
eventData: {
|
||||
eventTypeId,
|
||||
entity: {
|
||||
|
||||
@@ -15,15 +15,14 @@ import { HOSTED_CAL_FEATURES, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/consta
|
||||
import { emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
|
||||
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
||||
import { useLastUsed, LastUsed } from "@calcom/lib/hooks/useLastUsed";
|
||||
import { LastUsed, useLastUsed } from "@calcom/lib/hooks/useLastUsed";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
|
||||
import { collectPageParameters, telemetryEventTypes } from "@calcom/lib/telemetry";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { Alert } from "@calcom/ui/components/alert";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { EmailField } from "@calcom/ui/components/form";
|
||||
import { PasswordField } from "@calcom/ui/components/form";
|
||||
import { EmailField, PasswordField } from "@calcom/ui/components/form";
|
||||
|
||||
import type { inferSSRProps } from "@lib/types/inferSSRProps";
|
||||
import type { WithNonceProps } from "@lib/withNonce";
|
||||
@@ -254,12 +253,13 @@ PageProps & WithNonceProps<{}>) {
|
||||
defaultValue={totpEmail || (searchParams?.get("email") as string)}
|
||||
placeholder="john.doe@example.com"
|
||||
required
|
||||
autoComplete="email"
|
||||
{...register("email")}
|
||||
/>
|
||||
<div className="relative">
|
||||
<PasswordField
|
||||
id="password"
|
||||
autoComplete="off"
|
||||
autoComplete="current-password"
|
||||
required={!totpEmail}
|
||||
className="mb-0"
|
||||
{...register("password")}
|
||||
|
||||
@@ -8,7 +8,8 @@ import { useCallback, useState } from "react";
|
||||
|
||||
import { BulkEditDefaultForEventsModal } from "@calcom/features/eventtypes/components/BulkEditDefaultForEventsModal";
|
||||
import type { BulkUpdatParams } from "@calcom/features/eventtypes/components/BulkEditDefaultForEventsModal";
|
||||
import { NewScheduleButton, ScheduleListItem } from "@calcom/features/schedules";
|
||||
import { NewScheduleButton } from "@calcom/features/schedules/components/NewScheduleButton";
|
||||
import { ScheduleListItem } from "@calcom/features/schedules/components/ScheduleListItem";
|
||||
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
|
||||
@@ -5,8 +5,8 @@ import { z } from "zod";
|
||||
import { orgDomainConfig } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||
import getBookingInfo from "@calcom/features/bookings/lib/getBookingInfo";
|
||||
import { parseRecurringEvent } from "@calcom/lib";
|
||||
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
|
||||
import { BookingRepository } from "@calcom/lib/server/repository/booking";
|
||||
|
||||
@@ -236,6 +236,7 @@ export default function Success(props: PageProps) {
|
||||
if (eventType.isDynamic && bookingInfo.responses?.title) {
|
||||
evtName = bookingInfo.responses.title as string;
|
||||
}
|
||||
|
||||
const eventNameObject = {
|
||||
attendeeName: bookingInfo.responses.name as z.infer<typeof nameObjectSchema> | string,
|
||||
eventType: eventType.title,
|
||||
@@ -243,7 +244,7 @@ export default function Success(props: PageProps) {
|
||||
host: props.profile.name || "Nameless",
|
||||
location: location,
|
||||
bookingFields: bookingInfo.responses,
|
||||
eventDuration: eventType.length,
|
||||
eventDuration: dayjs(bookingInfo.endTime).diff(bookingInfo.startTime, "minutes"),
|
||||
t,
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import { EventTypeDescription } from "@calcom/features/eventtypes/components";
|
||||
import CreateEventTypeDialog from "@calcom/features/eventtypes/components/CreateEventTypeDialog";
|
||||
import { DuplicateDialog } from "@calcom/features/eventtypes/components/DuplicateDialog";
|
||||
import { InfiniteSkeletonLoader } from "@calcom/features/eventtypes/components/SkeletonLoader";
|
||||
import { parseEventTypeColor } from "@calcom/lib";
|
||||
import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { useCopy } from "@calcom/lib/hooks/useCopy";
|
||||
import { useDebounce } from "@calcom/lib/hooks/useDebounce";
|
||||
@@ -24,6 +23,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { useGetTheme } from "@calcom/lib/hooks/useTheme";
|
||||
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { parseEventTypeColor } from "@calcom/lib/isEventTypeColor";
|
||||
import type { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
@@ -596,7 +596,7 @@ export const InfiniteEventTypeList = ({
|
||||
variant="icon"
|
||||
color="secondary"
|
||||
StartIcon="ellipsis"
|
||||
// Unsual practice to use radix state open but for some reason this dropdown and only thi dropdown clears the border radius of this button.
|
||||
// Unusual practice to use radix state open but for some reason this dropdown and only this dropdown clears the border radius of this button.
|
||||
className="ltr:radix-state-open:rounded-r-[--btn-group-radius] rtl:radix-state-open:rounded-l-[--btn-group-radius]"
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function MaintenancePage() {
|
||||
return (
|
||||
<div className="bg-subtle flex h-screen">
|
||||
<div className="bg-default m-auto rounded-md p-10 text-right ltr:text-left">
|
||||
<h1 className="text-emphasis text-2xl font-medium">{t("down_for_maintenance")}</h1>
|
||||
<h1 className="text-emphasis text-2xl font-medium">{t("under_maintenance")}</h1>
|
||||
<p className="text-default mb-6 mt-4 max-w-2xl text-sm">{t("maintenance_message")}</p>
|
||||
<Button href={`${WEBSITE_URL}/support`}>{t("contact_support")}</Button>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,10 @@ import { usePathname } from "next/navigation";
|
||||
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
|
||||
import BillingCredits from "~/settings/billing/components/BillingCredits";
|
||||
|
||||
interface CtaRowProps {
|
||||
title: string;
|
||||
@@ -58,9 +60,9 @@ const BillingView = () => {
|
||||
{t("billing_portal")}
|
||||
</Button>
|
||||
</CtaRow>
|
||||
|
||||
<hr className="border-subtle" />
|
||||
|
||||
</div>
|
||||
<BillingCredits />
|
||||
<div className="border-subtle mt-6 space-y-6 rounded-lg border px-6 py-8 text-sm sm:space-y-8">
|
||||
<CtaRow title={t("need_anything_else")} description={t("further_billing_help")}>
|
||||
<Button color="secondary" onClick={onContactSupportClick}>
|
||||
{t("contact_support")}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
"use client";
|
||||
|
||||
import { ProgressBar } from "@tremor/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { IS_SMS_CREDITS_ENABLED } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { TextField, Label, InputError } from "@calcom/ui/components/form";
|
||||
import { showToast } from "@calcom/ui/toast";
|
||||
|
||||
import { BillingCreditsSkeleton } from "./BillingCreditsSkeleton";
|
||||
|
||||
export default function BillingCredits() {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<{ quantity: number }>({ defaultValues: { quantity: 50 } });
|
||||
|
||||
const params = useParamsWithFallback();
|
||||
|
||||
const teamId = params.id ? Number(params.id) : undefined;
|
||||
const { data: creditsData, isLoading } = trpc.viewer.credits.getAllCredits.useQuery({ teamId });
|
||||
|
||||
const buyCreditsMutation = trpc.viewer.credits.buyCredits.useMutation({
|
||||
onSuccess: (data) => {
|
||||
if (data.sessionUrl) {
|
||||
router.push(data.sessionUrl);
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
showToast(t("credit_purchase_failed"), "error");
|
||||
},
|
||||
});
|
||||
|
||||
if (!IS_SMS_CREDITS_ENABLED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isLoading && teamId) return <BillingCreditsSkeleton />;
|
||||
if (!creditsData) return null;
|
||||
|
||||
const onSubmit = (data: { quantity: number }) => {
|
||||
buyCreditsMutation.mutate({ quantity: data.quantity, teamId });
|
||||
};
|
||||
|
||||
const teamCreditsPercentageUsed =
|
||||
creditsData.credits.totalMonthlyCredits > 0
|
||||
? (creditsData.credits.totalRemainingMonthlyCredits / creditsData.credits.totalMonthlyCredits) * 100
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<div className="border-subtle mt-8 space-y-6 rounded-lg border px-6 py-6 pb-6 text-sm sm:space-y-8">
|
||||
<div>
|
||||
<h2 className="text-base font-semibold">{t("credits")}</h2>
|
||||
<p>{t("view_and_manage_credits_description")}</p>
|
||||
<div className="-mx-6 mt-6">
|
||||
<hr className="border-subtle" />
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
{creditsData.credits.totalMonthlyCredits > 0 ? (
|
||||
<div className="mb-4">
|
||||
<Label>{t("monthly_credits")}</Label>
|
||||
<ProgressBar
|
||||
color="green"
|
||||
percentageValue={teamCreditsPercentageUsed}
|
||||
label={`${Math.max(0, Math.round(teamCreditsPercentageUsed))}%`}
|
||||
/>
|
||||
<div className="text-subtle">
|
||||
<div>
|
||||
{t("total_credits", {
|
||||
totalCredits: creditsData.credits.totalMonthlyCredits,
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
{t("remaining_credits", {
|
||||
remainingCredits: creditsData.credits.totalRemainingMonthlyCredits,
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
<Label>
|
||||
{creditsData.credits.totalMonthlyCredits ? t("additional_credits") : t("available_credits")}
|
||||
</Label>
|
||||
<div className="mt-2 text-sm">{creditsData.credits.additionalCredits}</div>
|
||||
<div className="-mx-6 mb-6 mt-6">
|
||||
<hr className="border-subtle mb-3 mt-3" />
|
||||
</div>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="flex">
|
||||
<div className="mr-auto">
|
||||
<div className="mb-2 font-semibold">{t("buy_additional_credits")}</div>
|
||||
<div className="flex flex-col">
|
||||
<TextField
|
||||
required
|
||||
type="number"
|
||||
{...register("quantity", {
|
||||
required: t("error_required_field"),
|
||||
min: { value: 50, message: t("minimum_of_credits_required") },
|
||||
valueAsNumber: true,
|
||||
})}
|
||||
label=""
|
||||
containerClassName="w-60"
|
||||
onChange={(e) => setValue("quantity", Number(e.target.value))}
|
||||
min={50}
|
||||
addOnSuffix={<>{t("credits")}</>}
|
||||
/>
|
||||
{errors.quantity && <InputError message={errors.quantity.message ?? t("invalid_input")} />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-1 mt-auto">
|
||||
<Button color="primary" target="_blank" EndIcon="external-link" type="submit">
|
||||
{t("buy_credits")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { SkeletonText, SkeletonContainer, SkeletonButton } from "@calcom/ui/components/skeleton";
|
||||
|
||||
export function BillingCreditsSkeleton() {
|
||||
return (
|
||||
<SkeletonContainer>
|
||||
<div className="border-subtle mt-8 space-y-6 rounded-lg border px-6 py-6 text-sm sm:space-y-8">
|
||||
{/* Title and Description */}
|
||||
<div>
|
||||
<div>
|
||||
<SkeletonText className="mb-2 h-4 w-20" /> {/* Credits title */}
|
||||
</div>
|
||||
<div>
|
||||
<SkeletonText className="h-4 w-72" /> {/* Description */}
|
||||
</div>
|
||||
|
||||
<div className="-mx-6 mt-6">
|
||||
<hr className="border-subtle" />
|
||||
</div>
|
||||
{/* Monthly credits */}
|
||||
<div className="mt-[20px]">
|
||||
<SkeletonText className="mb-4 h-4 w-32" /> {/* Monthly credits label */}
|
||||
<div className="h-2 w-full rounded-md bg-gray-200" /> {/* Progress bar */}
|
||||
<div className="text-subtle mt-2">
|
||||
<div>
|
||||
<SkeletonText className="h-4 w-40" /> {/* Total credits */}
|
||||
</div>
|
||||
<div>
|
||||
<SkeletonText className="h-4 w-40" /> {/* Remaining credits */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Additional credits */}
|
||||
<div className="mt-4">
|
||||
<div>
|
||||
<SkeletonText className="mb-2 h-4 w-40" /> {/* Additional credits label */}
|
||||
</div>
|
||||
<div>
|
||||
<SkeletonText className="h-4 w-24" /> {/* Additional credits value */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="-mx-6 mb-6 mt-4">
|
||||
<hr className="border-subtle mb-3 mt-3" />
|
||||
</div>
|
||||
{/* Buy credits form */}
|
||||
<div className="flex">
|
||||
<div className="mr-auto">
|
||||
<div>
|
||||
<SkeletonText className="mb-2 mt-1 h-5 w-[268px]" /> {/* Buy credits label */}
|
||||
</div>
|
||||
<div>
|
||||
<SkeletonText className="mt-2 h-8 w-[240px] rounded-md" /> {/* Input field */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-auto ">
|
||||
<SkeletonButton className="h-9 w-[120px] rounded-md" /> {/* Buy button */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SkeletonContainer>
|
||||
);
|
||||
}
|
||||
@@ -408,9 +408,11 @@ export default function Signup({
|
||||
) : null}
|
||||
{/* Email */}
|
||||
<TextField
|
||||
id="signup-email"
|
||||
{...register("email")}
|
||||
label={t("email")}
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
disabled={prepopulateFormValues?.email}
|
||||
data-testid="signup-emailfield"
|
||||
/>
|
||||
@@ -418,7 +420,9 @@ export default function Signup({
|
||||
{/* Password */}
|
||||
{!isSamlSignup && (
|
||||
<PasswordField
|
||||
id="signup-password"
|
||||
data-testid="signup-passwordfield"
|
||||
autoComplete="new-password"
|
||||
label={t("password")}
|
||||
{...register("password")}
|
||||
hintErrors={["caplow", "min", "num"]}
|
||||
|
||||
@@ -35,6 +35,7 @@ function Type({
|
||||
crmOwnerRecordType,
|
||||
crmAppSlug,
|
||||
isEmbed,
|
||||
useApiV2,
|
||||
}: PageProps) {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
@@ -42,6 +43,7 @@ function Type({
|
||||
<BookingPageErrorBoundary>
|
||||
<main className={getBookerWrapperClasses({ isEmbed: !!isEmbed })}>
|
||||
<Booker
|
||||
useApiV2={useApiV2}
|
||||
username={user}
|
||||
eventSlug={slug}
|
||||
bookingData={booking}
|
||||
|
||||
+1
-52
@@ -1,9 +1,6 @@
|
||||
require("dotenv").config({ path: "../../.env" });
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const os = require("os");
|
||||
const englishTranslation = require("./public/static/locales/en/common.json");
|
||||
const { withAxiom } = require("next-axiom");
|
||||
const { withSentryConfig } = require("@sentry/nextjs");
|
||||
const { version } = require("./package.json");
|
||||
const {
|
||||
i18n: { locales },
|
||||
@@ -190,9 +187,8 @@ const nextConfig = {
|
||||
experimental: {
|
||||
// externalize server-side node_modules with size > 1mb, to improve dev mode performance/RAM usage
|
||||
optimizePackageImports: ["@calcom/ui"],
|
||||
turbo: {},
|
||||
},
|
||||
productionBrowserSourceMaps: process.env.SENTRY_DISABLE_CLIENT_SOURCE_MAPS === "0",
|
||||
productionBrowserSourceMaps: true,
|
||||
/* We already do type check on GH actions */
|
||||
typescript: {
|
||||
ignoreBuildErrors: !!process.env.CI,
|
||||
@@ -228,10 +224,6 @@ const nextConfig = {
|
||||
},
|
||||
webpack: (config, { webpack, buildId, isServer }) => {
|
||||
if (isServer) {
|
||||
if (process.env.SENTRY_DISABLE_SERVER_SOURCE_MAPS === "1") {
|
||||
config.devtool = false;
|
||||
}
|
||||
|
||||
// Module not found fix @see https://github.com/boxyhq/jackson/issues/1535#issuecomment-1704381612
|
||||
config.plugins.push(
|
||||
new webpack.IgnorePlugin({
|
||||
@@ -243,34 +235,6 @@ const nextConfig = {
|
||||
config.externals.push("formidable");
|
||||
}
|
||||
|
||||
config.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
__SENTRY_DEBUG__: false,
|
||||
__SENTRY_TRACING__: false,
|
||||
})
|
||||
);
|
||||
|
||||
config.plugins.push(
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: "../../packages/app-store/**/static/**",
|
||||
to({ context, absoluteFilename }) {
|
||||
// Adds compatibility for windows path
|
||||
if (os.platform() === "win32") {
|
||||
const absoluteFilenameWin = absoluteFilename.replaceAll("\\", "/");
|
||||
const contextWin = context.replaceAll("\\", "/");
|
||||
const appName = /app-store\/(.*)\/static/.exec(absoluteFilenameWin);
|
||||
return Promise.resolve(`${contextWin}/public/app-store/${appName[1]}/[name][ext]`);
|
||||
}
|
||||
const appName = /app-store\/(.*)\/static/.exec(absoluteFilename);
|
||||
return Promise.resolve(`${context}/public/app-store/${appName[1]}/[name][ext]`);
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
config.plugins.push(new webpack.DefinePlugin({ "process.env.BUILD_ID": JSON.stringify(buildId) }));
|
||||
|
||||
config.resolve.fallback = {
|
||||
@@ -714,19 +678,4 @@ const nextConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
if (!!process.env.NEXT_PUBLIC_SENTRY_DSN) {
|
||||
plugins.push((nextConfig) =>
|
||||
withSentryConfig(nextConfig, {
|
||||
autoInstrumentServerFunctions: false,
|
||||
hideSourceMaps: true,
|
||||
// disable source map generation for the server code
|
||||
disableServerWebpackPlugin: !!process.env.SENTRY_DISABLE_SERVER_WEBPACK_PLUGIN,
|
||||
silent: false,
|
||||
sourcemaps: {
|
||||
disable: process.env.SENTRY_DISABLE_SERVER_SOURCE_MAPS === "1",
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = () => plugins.reduce((acc, next) => next(acc), nextConfig);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "5.2.13",
|
||||
"version": "5.2.17",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
"analyze:server": "BUNDLE_ANALYZE=server next build",
|
||||
"analyze:browser": "BUNDLE_ANALYZE=browser next build",
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
|
||||
"dev": "next dev --turbopack",
|
||||
"dev": "yarn copy-static && next dev --turbopack",
|
||||
"dev:cron": "ts-node cron-tester.ts",
|
||||
"dev-https": "NODE_TLS_REJECT_UNAUTHORIZED=0 next dev --experimental-https",
|
||||
"dx": "yarn dev",
|
||||
"test-codegen": "yarn playwright codegen http://localhost:3000",
|
||||
"type-check": "tsc --pretty --noEmit",
|
||||
"type-check:ci": "tsc-absolute --pretty --noEmit",
|
||||
"build": "next build",
|
||||
"sentry:release": "NODE_OPTIONS='--max-old-space-size=6144' node scripts/create-sentry-release.js",
|
||||
"copy-static": "node scripts/copy-app-store-static.js",
|
||||
"build": "yarn copy-static && next build && yarn sentry:release",
|
||||
"start": "next start",
|
||||
"lint": "eslint . --ignore-path .gitignore",
|
||||
"lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix",
|
||||
@@ -69,7 +71,7 @@
|
||||
"@radix-ui/react-switch": "^1.0.0",
|
||||
"@radix-ui/react-toggle-group": "^1.0.0",
|
||||
"@radix-ui/react-tooltip": "^1.0.0",
|
||||
"@sentry/nextjs": "^9.8.0",
|
||||
"@sentry/nextjs": "^9.15.0",
|
||||
"@stripe/react-stripe-js": "^1.10.0",
|
||||
"@stripe/stripe-js": "^1.35.0",
|
||||
"@tanstack/react-query": "^5.17.15",
|
||||
@@ -179,10 +181,10 @@
|
||||
"@types/stripe": "^8.0.417",
|
||||
"@types/uuid": "8.3.1",
|
||||
"autoprefixer": "^10.4.12",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"cron": "^3.1.7",
|
||||
"detect-port": "^1.3.0",
|
||||
"env-cmd": "^10.1.0",
|
||||
"glob": "^10.3.10",
|
||||
"google-auth-library": "^9.15.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"msw": "^0.42.3",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createNextApiHandler } from "@calcom/trpc/server/createNextApiHandler";
|
||||
import { creditsRouter } from "@calcom/trpc/server/routers/viewer/credits/_router";
|
||||
|
||||
export default createNextApiHandler(creditsRouter);
|
||||
@@ -0,0 +1,167 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { z } from "zod";
|
||||
|
||||
import * as twilio from "@calcom/features/ee/workflows/lib/reminders/providers/twilioProvider";
|
||||
import { IS_SMS_CREDITS_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
|
||||
import { defaultHandler } from "@calcom/lib/server/defaultHandler";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
const InputSchema = z.object({
|
||||
userId: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => {
|
||||
const num = Number(val);
|
||||
return isNaN(num) ? undefined : num;
|
||||
}),
|
||||
teamId: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => {
|
||||
const num = Number(val);
|
||||
return isNaN(num) ? undefined : num;
|
||||
}),
|
||||
bookingUid: z.string().optional(),
|
||||
});
|
||||
|
||||
/*
|
||||
Twilio status callback: creates expense log when sms is delivered or undelivered
|
||||
*/
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const signature = req.headers["x-twilio-signature"];
|
||||
const baseUrl = `${WEBAPP_URL}/api/twilio/webhook`;
|
||||
|
||||
const queryParams = new URLSearchParams(req.query as Record<string, string>).toString();
|
||||
const requestUrl = queryParams ? `${baseUrl}?${queryParams}` : baseUrl;
|
||||
|
||||
if (typeof signature !== "string") {
|
||||
return res.status(401).send("Missing Twilio signature");
|
||||
}
|
||||
|
||||
const isSignatureValid = await twilio.validateWebhookRequest({
|
||||
requestUrl,
|
||||
signature,
|
||||
params: req.body,
|
||||
});
|
||||
|
||||
if (!isSignatureValid) {
|
||||
return res.status(401).send("Invalid Twilio signature");
|
||||
}
|
||||
|
||||
const messageStatus = req.body.MessageStatus;
|
||||
|
||||
if (messageStatus !== "delivered" && messageStatus !== "undelivered") {
|
||||
return res.status(200).send(`SMS not yet delivered/undelivered`);
|
||||
}
|
||||
|
||||
if (!IS_SMS_CREDITS_ENABLED) {
|
||||
return res.status(200).send(`SMS credits are not enabled.`);
|
||||
}
|
||||
|
||||
const countryCode = await twilio.getCountryCodeForNumber(req.body.To);
|
||||
|
||||
const smsSid = req.body.SmsSid;
|
||||
|
||||
const {
|
||||
userId: parsedUserId,
|
||||
teamId: parsedTeamId,
|
||||
bookingUid: parsedBookingUid,
|
||||
} = InputSchema.parse(req.query);
|
||||
|
||||
if (!parsedUserId && !parsedTeamId) {
|
||||
return res.status(401).send("Team or user id is required");
|
||||
}
|
||||
const { CreditService } = await import("@calcom/features/ee/billing/credit-service");
|
||||
const creditService = new CreditService();
|
||||
|
||||
if (countryCode === "US" || countryCode === "CA") {
|
||||
// SMS to US and CA are free on a team plan
|
||||
let teamIdToCharge = parsedTeamId;
|
||||
|
||||
if (!teamIdToCharge && parsedUserId) {
|
||||
const teamMembership = await prisma.membership.findFirst({
|
||||
where: {
|
||||
userId: parsedUserId,
|
||||
accepted: true,
|
||||
},
|
||||
select: {
|
||||
teamId: true,
|
||||
},
|
||||
});
|
||||
teamIdToCharge = teamMembership?.teamId;
|
||||
}
|
||||
|
||||
await creditService.chargeCredits({
|
||||
teamId: teamIdToCharge,
|
||||
userId: !teamIdToCharge ? parsedUserId : undefined,
|
||||
bookingUid: parsedBookingUid,
|
||||
smsSid,
|
||||
credits: 0,
|
||||
});
|
||||
|
||||
return res.status(200).send(`SMS to US and CA are free on a team plan. Credits set to 0`);
|
||||
}
|
||||
|
||||
let orgId;
|
||||
|
||||
if (parsedTeamId) {
|
||||
const team = await prisma.team.findUnique({
|
||||
where: {
|
||||
id: parsedTeamId,
|
||||
},
|
||||
select: {
|
||||
isOrganization: true,
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
orgId = team?.isOrganization ? team.id : undefined;
|
||||
}
|
||||
|
||||
if (!orgId) {
|
||||
orgId = await getOrgIdFromMemberOrTeamId({
|
||||
memberId: parsedUserId,
|
||||
teamId: parsedTeamId,
|
||||
});
|
||||
}
|
||||
|
||||
if (orgId) {
|
||||
await creditService.chargeCredits({
|
||||
teamId: orgId,
|
||||
bookingUid: parsedBookingUid,
|
||||
smsSid,
|
||||
credits: 0,
|
||||
});
|
||||
|
||||
return res.status(200).send(`SMS are free for organizations. Credits set to 0`);
|
||||
}
|
||||
|
||||
const price = await twilio.getPriceForSMS(smsSid);
|
||||
|
||||
const credits = price ? creditService.calculateCreditsFromPrice(price) : null;
|
||||
|
||||
const chargedUserOrTeamId = await creditService.chargeCredits({
|
||||
credits,
|
||||
teamId: parsedTeamId,
|
||||
userId: parsedUserId,
|
||||
smsSid,
|
||||
bookingUid: parsedBookingUid,
|
||||
});
|
||||
|
||||
if (chargedUserOrTeamId) {
|
||||
return res.status(200).send(
|
||||
`Expense log with ${credits ? credits : "no"} credits created for
|
||||
${
|
||||
chargedUserOrTeamId.teamId
|
||||
? `teamId ${chargedUserOrTeamId.teamId}`
|
||||
: `userId ${chargedUserOrTeamId.userId}`
|
||||
}`
|
||||
);
|
||||
}
|
||||
// this should never happen - even when out of credits we still charge a team
|
||||
return res.status(500).send("No team or users found to be charged");
|
||||
}
|
||||
|
||||
export default defaultHandler({
|
||||
POST: Promise.resolve({ default: handler }),
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import type { Page } from "@playwright/test";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/client";
|
||||
@@ -72,7 +73,7 @@ test.describe("Bookings", () => {
|
||||
const bookingsGetResponse = page.waitForResponse((response) =>
|
||||
/\/api\/trpc\/bookings\/get.*/.test(response.url())
|
||||
);
|
||||
await page.goto(`/bookings/upcoming`);
|
||||
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
|
||||
await bookingsGetResponse;
|
||||
|
||||
await page.locator('[data-testid="add-filter-button"]').click();
|
||||
@@ -350,7 +351,7 @@ test.describe("Bookings", () => {
|
||||
const bookingsGetResponse = page.waitForResponse((response) =>
|
||||
/\/api\/trpc\/bookings\/get.*/.test(response.url())
|
||||
);
|
||||
await page.goto(`/bookings/upcoming`);
|
||||
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
|
||||
await bookingsGetResponse;
|
||||
|
||||
await page.locator('[data-testid="add-filter-button"]').click();
|
||||
@@ -361,7 +362,7 @@ test.describe("Bookings", () => {
|
||||
(response) => response.url().includes("/api/trpc/bookings/get?batch=1") && response.status() === 200
|
||||
);
|
||||
await page
|
||||
.locator(`[data-testid="multi-select-options-userId"] [role="option"]:has-text("${thirdUser.name}")`)
|
||||
.locator(`[data-testid="select-filter-options-userId"] [role="option"]:has-text("${thirdUser.name}")`)
|
||||
.click();
|
||||
await bookingsGetResponse2;
|
||||
await expect(page.locator('text="Cancel event"').nth(0)).toBeVisible();
|
||||
@@ -457,19 +458,108 @@ test.describe("Bookings", () => {
|
||||
const bookingsGetResponse1 = page.waitForResponse((response) =>
|
||||
/\/api\/trpc\/bookings\/get.*/.test(response.url())
|
||||
);
|
||||
await page.goto("/bookings/upcoming");
|
||||
await page.goto("/bookings/upcoming", { waitUntil: "domcontentloaded" });
|
||||
await bookingsGetResponse1;
|
||||
|
||||
await page.locator('[data-testid="add-filter-button"]').click();
|
||||
await page.locator('[data-testid="add-filter-item-userId"]').click();
|
||||
await page.locator('[data-testid="filter-popover-trigger-userId"]').click();
|
||||
await page
|
||||
.locator(`[data-testid="multi-select-options-userId"] [role="option"]:has-text("${anotherUser}")`)
|
||||
.locator(`[data-testid="select-filter-options-userId"] [role="option"]:has-text("${anotherUser}")`)
|
||||
.click();
|
||||
await page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url()));
|
||||
|
||||
await expect(page.locator('[data-testid="booking-item"]')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test.describe("Filter Dropdown Item Search", () => {
|
||||
const filterItemsConfig = [
|
||||
{ key: "eventTypeId", name: "Event Type", testId: "add-filter-item-eventTypeId" },
|
||||
{ key: "teamId", name: "Team", testId: "add-filter-item-teamId" },
|
||||
{ key: "userId", name: "Member", testId: "add-filter-item-userId" },
|
||||
{ key: "attendeeName", name: "Attendees Name", testId: "add-filter-item-attendeeName" },
|
||||
{ key: "attendeeEmail", name: "Attendee Email", testId: "add-filter-item-attendeeEmail" },
|
||||
{ key: "dateRange", name: "Date Range", testId: "add-filter-item-dateRange" },
|
||||
];
|
||||
const searchInputSelector = "[cmdk-input]";
|
||||
|
||||
const getFilterItemLocator = (page: Page, testId: string) => page.locator(`[data-testid="${testId}"]`);
|
||||
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const user = await users.create();
|
||||
await user.apiLogin();
|
||||
const bookingsGetResponse = page.waitForResponse((response) =>
|
||||
/\/api\/trpc\/bookings\/get.*/.test(response.url())
|
||||
);
|
||||
await page.goto(`/bookings/upcoming`, { waitUntil: "domcontentloaded" });
|
||||
await bookingsGetResponse;
|
||||
await page.locator('[data-testid="add-filter-button"]').click();
|
||||
await expect(page.locator(searchInputSelector)).toBeVisible();
|
||||
});
|
||||
|
||||
test("should show all filter items initially and after clearing search", async ({ page }) => {
|
||||
const searchInput = page.locator(searchInputSelector);
|
||||
|
||||
// Initial check: all defined filter items should be visible
|
||||
for (const item of filterItemsConfig) {
|
||||
await expect(
|
||||
getFilterItemLocator(page, item.testId),
|
||||
`Item ${item.name} should be visible initially`
|
||||
).toBeVisible();
|
||||
}
|
||||
|
||||
// Type something and then clear the search
|
||||
await searchInput.fill("Some text");
|
||||
await searchInput.clear();
|
||||
|
||||
// After clearing: all defined filter items should be visible again
|
||||
for (const item of filterItemsConfig) {
|
||||
await expect(
|
||||
getFilterItemLocator(page, item.testId),
|
||||
`Item ${item.name} should be visible after clearing search`
|
||||
).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test("search should be case-insensitive", async ({ page }) => {
|
||||
const searchInput = page.locator(searchInputSelector);
|
||||
|
||||
// Search for "member" (lowercase)
|
||||
await searchInput.fill("member");
|
||||
await expect(getFilterItemLocator(page, "add-filter-item-userId")).toBeVisible();
|
||||
await expect(getFilterItemLocator(page, "add-filter-item-eventTypeId")).toBeHidden();
|
||||
await expect(getFilterItemLocator(page, "add-filter-item-teamId")).toBeHidden();
|
||||
});
|
||||
|
||||
test("should individually find each filter item by its full name", async ({ page }) => {
|
||||
const searchInput = page.locator(searchInputSelector);
|
||||
|
||||
for (const targetItem of filterItemsConfig) {
|
||||
await searchInput.fill(targetItem.name);
|
||||
|
||||
// Check that the target item is visible
|
||||
await expect(
|
||||
getFilterItemLocator(page, targetItem.testId),
|
||||
`Searching for "${targetItem.name}", item "${targetItem.name}" should be visible`
|
||||
).toBeVisible();
|
||||
|
||||
await searchInput.clear();
|
||||
}
|
||||
});
|
||||
|
||||
test("should show no items for a non-matching search term", async ({ page }) => {
|
||||
const searchInput = page.locator(searchInputSelector);
|
||||
const nonExistentTerm = "NonExistentFilterXYZ123";
|
||||
await searchInput.fill(nonExistentTerm);
|
||||
|
||||
for (const item of filterItemsConfig) {
|
||||
await expect(
|
||||
getFilterItemLocator(page, item.testId),
|
||||
`Item ${item.name} should be hidden for non-matching term '${nonExistentTerm}'`
|
||||
).toBeHidden();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function createBooking({
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Select a filter from the filter dropdown
|
||||
*/
|
||||
export async function selectFilter(page: Page, columnId: string) {
|
||||
await page.getByTestId("add-filter-button").click();
|
||||
await page.getByTestId(`add-filter-item-${columnId}`).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a filter with a specific value
|
||||
*/
|
||||
export async function applyFilter(page: Page, columnId: string, value: string) {
|
||||
const existingFilter = page.getByTestId(`filter-popover-trigger-${columnId}`);
|
||||
if (!(await existingFilter.isVisible())) {
|
||||
await selectFilter(page, columnId);
|
||||
}
|
||||
|
||||
await page.getByTestId(`filter-popover-trigger-${columnId}`).click();
|
||||
|
||||
await page.getByTestId(`select-filter-options-${columnId}`).getByRole("option", { name: value }).click();
|
||||
|
||||
await page.keyboard.press("Escape");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all filters
|
||||
*/
|
||||
export async function clearFilters(page: Page) {
|
||||
await page.getByTestId("clear-filters-button").click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a filter segment
|
||||
*/
|
||||
export async function createFilterSegment(
|
||||
page: Page,
|
||||
name: string,
|
||||
options: { teamScope?: boolean; teamName?: string } = {}
|
||||
) {
|
||||
await page.getByTestId("save-filter-segment-button").click();
|
||||
|
||||
await page.getByTestId("save-filter-segment-name").fill(name);
|
||||
|
||||
if (options.teamScope) {
|
||||
await page.getByLabel("Save for team").click();
|
||||
if (options.teamName) {
|
||||
await page.getByTestId("save-filter-segment-team-select").click();
|
||||
await page
|
||||
.locator('[data-testid="save-filter-segment-dialog"] [id^="react-select-"]')
|
||||
.getByText(options.teamName)
|
||||
.click();
|
||||
}
|
||||
}
|
||||
|
||||
await page.getByTestId("save-filter-segment-dialog").getByRole("button", { name: "Save" }).click();
|
||||
|
||||
await expect(page.getByText("Filter segment saved")).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a segment from the dropdown
|
||||
*/
|
||||
export async function selectSegment(page: Page, segmentName: string) {
|
||||
await page.getByTestId("filter-segment-select").click();
|
||||
|
||||
await page
|
||||
.locator('[data-testid="filter-segment-select-content"] [role="menuitem"]')
|
||||
.filter({ hasText: segmentName })
|
||||
.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open submenu of a certain segment
|
||||
*/
|
||||
export async function openSegmentSubmenu(page: Page, segmentName: string) {
|
||||
await page.getByTestId("filter-segment-select").click();
|
||||
|
||||
await page
|
||||
.locator('[data-testid="filter-segment-select-content"] [role="menuitem"]')
|
||||
.filter({ hasText: segmentName })
|
||||
.locator('[data-testid="filter-segment-select-submenu-button"]')
|
||||
.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a segment
|
||||
*/
|
||||
export async function deleteSegment(page: Page, segmentName: string) {
|
||||
openSegmentSubmenu(page, segmentName);
|
||||
|
||||
await page.getByTestId("filter-segment-select-submenu-content").getByText("Delete").click();
|
||||
|
||||
await page
|
||||
.locator('[role="dialog"]')
|
||||
.filter({ hasText: "Delete Segment" })
|
||||
.getByRole("button", { name: "Delete" })
|
||||
.click();
|
||||
|
||||
await page.keyboard.press("Escape");
|
||||
await expect(page.getByText("Filter segment deleted")).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available segments
|
||||
*/
|
||||
export async function listSegments(page: Page): Promise<string[]> {
|
||||
await page.getByTestId("filter-segment-select").click();
|
||||
|
||||
const menuItems = page.locator('[data-testid="filter-segment-select-content"] [role="menuitem"]');
|
||||
const count = await menuItems.count();
|
||||
|
||||
const segments: string[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const text = await menuItems.nth(i).innerText();
|
||||
segments.push(text);
|
||||
}
|
||||
|
||||
await page.keyboard.press("Escape");
|
||||
return segments;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import {
|
||||
applyFilter,
|
||||
createFilterSegment,
|
||||
selectSegment,
|
||||
deleteSegment,
|
||||
listSegments,
|
||||
clearFilters,
|
||||
openSegmentSubmenu,
|
||||
} from "./filter-helpers";
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.afterEach(async ({ users, orgs }) => {
|
||||
await users.deleteAll();
|
||||
await orgs.deleteAll();
|
||||
});
|
||||
|
||||
test.describe("Filter Segment Functionality", () => {
|
||||
test("Admin can create, use, and delete filter segments in organization members list", async ({
|
||||
page,
|
||||
users,
|
||||
orgs,
|
||||
}) => {
|
||||
const orgOwner = await users.create(undefined, {
|
||||
hasTeam: true,
|
||||
isOrg: true,
|
||||
});
|
||||
const { team: org } = await orgOwner.getOrgMembership();
|
||||
|
||||
const memberUser = await users.create({
|
||||
roleInOrganization: MembershipRole.MEMBER,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "member-user",
|
||||
});
|
||||
|
||||
const adminUser = await users.create({
|
||||
roleInOrganization: MembershipRole.ADMIN,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "admin-user",
|
||||
});
|
||||
|
||||
await orgOwner.apiLogin();
|
||||
|
||||
await page.goto(`/settings/organizations/${org.slug}/members`);
|
||||
|
||||
const dataTable = page.getByTestId("user-list-data-table");
|
||||
await expect(dataTable).toBeVisible();
|
||||
|
||||
const segmentName = "Admin Users";
|
||||
|
||||
await test.step("Can apply and save a role filter as a segment", async () => {
|
||||
await applyFilter(page, "role", "admin");
|
||||
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeHidden();
|
||||
|
||||
await createFilterSegment(page, segmentName);
|
||||
|
||||
await clearFilters(page);
|
||||
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeVisible();
|
||||
|
||||
await selectSegment(page, segmentName);
|
||||
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeHidden();
|
||||
});
|
||||
|
||||
await test.step("Can delete a filter segment", async () => {
|
||||
await deleteSegment(page, "Admin Users");
|
||||
|
||||
const segments = await listSegments(page);
|
||||
expect(segments.includes(segmentName)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
test("Filter segments persist across page reloads", async ({ page, users, orgs }) => {
|
||||
const orgOwner = await users.create(undefined, {
|
||||
hasTeam: true,
|
||||
isOrg: true,
|
||||
});
|
||||
const { team: org } = await orgOwner.getOrgMembership();
|
||||
|
||||
const memberUser = await users.create({
|
||||
roleInOrganization: MembershipRole.MEMBER,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "member-user",
|
||||
});
|
||||
|
||||
const adminUser = await users.create({
|
||||
roleInOrganization: MembershipRole.ADMIN,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "admin-user",
|
||||
});
|
||||
|
||||
await orgOwner.apiLogin();
|
||||
|
||||
await page.goto(`/settings/organizations/${org.slug}/members`);
|
||||
|
||||
const dataTable = page.getByTestId("user-list-data-table");
|
||||
await expect(dataTable).toBeVisible();
|
||||
|
||||
await applyFilter(page, "role", "admin");
|
||||
const segmentName = "Admin Users Persistent";
|
||||
await createFilterSegment(page, segmentName);
|
||||
|
||||
await page.reload();
|
||||
await expect(dataTable).toBeVisible();
|
||||
|
||||
await selectSegment(page, segmentName);
|
||||
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeHidden();
|
||||
|
||||
await deleteSegment(page, segmentName);
|
||||
});
|
||||
|
||||
test("Admin can create and use team scope filter segments", async ({ page, users, prisma }) => {
|
||||
const orgOwner = await users.create(undefined, {
|
||||
hasTeam: true,
|
||||
isOrg: true,
|
||||
|
||||
hasSubteam: true,
|
||||
});
|
||||
const { team: org } = await orgOwner.getOrgMembership();
|
||||
const { team: subTeam } = await orgOwner.getFirstTeamMembership();
|
||||
|
||||
const memberUser = await users.create({
|
||||
roleInOrganization: MembershipRole.MEMBER,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "org-member",
|
||||
});
|
||||
|
||||
const adminUser = await users.create({
|
||||
roleInOrganization: MembershipRole.ADMIN,
|
||||
organizationId: org.id,
|
||||
|
||||
username: "org-admin",
|
||||
});
|
||||
|
||||
await orgOwner.apiLogin();
|
||||
|
||||
await page.goto(`/settings/organizations/${org.slug}/members`);
|
||||
|
||||
const dataTable = page.getByTestId("user-list-data-table");
|
||||
await expect(dataTable).toBeVisible();
|
||||
const segmentName = "Team Admin Filter";
|
||||
|
||||
await test.step("Can create a team scope filter segment", async () => {
|
||||
await applyFilter(page, "role", "admin");
|
||||
|
||||
await createFilterSegment(page, segmentName, {
|
||||
teamScope: true,
|
||||
teamName: subTeam.name,
|
||||
});
|
||||
|
||||
await clearFilters(page);
|
||||
await selectSegment(page, segmentName);
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeHidden();
|
||||
});
|
||||
|
||||
await test.step("Regular member can see but not modify team segments", async () => {
|
||||
const regularMember = await users.create({
|
||||
roleInOrganization: MembershipRole.MEMBER,
|
||||
organizationId: org.id,
|
||||
username: "regular-member",
|
||||
});
|
||||
await prisma.membership.create({
|
||||
data: {
|
||||
createdAt: new Date(),
|
||||
teamId: subTeam.id,
|
||||
userId: regularMember.id,
|
||||
role: MembershipRole.MEMBER,
|
||||
accepted: true,
|
||||
},
|
||||
});
|
||||
|
||||
await regularMember.apiLogin();
|
||||
|
||||
await page.goto(`/settings/organizations/${org.slug}/members`);
|
||||
await expect(dataTable).toBeVisible();
|
||||
|
||||
await selectSegment(page, "Team Admin Filter");
|
||||
await expect(page.getByText(adminUser.email)).toBeVisible();
|
||||
await expect(page.getByText(memberUser.email)).toBeHidden();
|
||||
|
||||
await openSegmentSubmenu(page, segmentName);
|
||||
await expect(
|
||||
page.getByTestId("filter-segment-select-submenu-content").getByText("Delete")
|
||||
).toBeHidden();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -212,13 +212,13 @@ test.describe("Insights", async () => {
|
||||
await page.getByTestId("filter-popover-trigger-bookingUserId").click();
|
||||
|
||||
await page
|
||||
.locator('[data-testid="single-select-options-bookingUserId"]')
|
||||
.locator('[data-testid="select-filter-options-bookingUserId"]')
|
||||
.getByRole("option")
|
||||
.nth(0)
|
||||
.click();
|
||||
|
||||
await page
|
||||
.locator('[data-testid="single-select-options-bookingUserId"]')
|
||||
.locator('[data-testid="select-filter-options-bookingUserId"]')
|
||||
.getByRole("option")
|
||||
.nth(1)
|
||||
.click();
|
||||
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "اسمك الكامل",
|
||||
"no_name": "لا يوجد اسم",
|
||||
"enter_number_between_range": "الرجاء إدخال رقم بين 1 و {{maxOccurences}}",
|
||||
"continue_as_guest_description": "سريع وسهل - لا يتطلب حساباً. مثالي للاجتماعات لمرة واحدة.",
|
||||
"email_address": "عنوان البريد الإلكتروني",
|
||||
"enter_valid_email": "يرجى إدخال بريد إلكتروني صالح",
|
||||
"please_schedule_future_call": " الرجاء جدولة مكالمة مستقبلية إذا لم نكن متاحين خلال {{seconds}} ثانية",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "شخصيًا (عنوان من سيحضر)",
|
||||
"somewhere_else": "مكان آخر",
|
||||
"custom_attendee_location": "موقع الحضور المخصص",
|
||||
"continue_as_guest": "المتابعة كضيف",
|
||||
"any_location": "أي موقع",
|
||||
"yes": "نعم",
|
||||
"no": "لا",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "تم تحديث الفريق بنجاح",
|
||||
"your_team_updated_successfully": "تم تحديث فريقك بنجاح.",
|
||||
"your_org_updated_successfully": "تم تحديث منظمتك بنجاح.",
|
||||
"error_copying_to_clipboard": "خطأ في النسخ إلى الحافظة",
|
||||
"about": "حول",
|
||||
"team_description": "بضع جمل عن فريقك. ستظهر على صفحة رابط فريقك.",
|
||||
"organization_id": "معرّف المؤسسة",
|
||||
"organization_id_copied": "تم نسخ معرّف المؤسسة.",
|
||||
"org_description": "بضع جمل عن منظمتك. ستظهر على صفحة رابط منظمتك.",
|
||||
"team_id": "معرّف الفريق",
|
||||
"team_id_copied": "تم نسخ معرّف الفريق.",
|
||||
"members": "الأعضاء",
|
||||
"organization_members": "أعضاء Organization",
|
||||
"member": "العضو",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "هل تريد بالتأكيد إزالة هذا العضو من الفريق؟",
|
||||
"confirm_disband_team": "نعم، أريد تفكيك الفريق",
|
||||
"confirm_remove_member": "نعم، أريد إزالة العضو",
|
||||
"confirm_subscription_cancellation": "نعم، إلغاء الاشتراك",
|
||||
"cancel_subscription": "إلغاء الاشتراك",
|
||||
"cancel_subscription_description": "إلغاء اشتراكك سيؤدي إلى تعطيل خطتك الحالية بشكل دائم. لا يمكن التراجع عن هذا الإجراء.",
|
||||
"remove_member": "إزالة العضو",
|
||||
"manage_your_team": "إدارة الفريق",
|
||||
"no_teams": "ليس لديك أي فرق حتى الآن.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "رابط صفحة الحجز الخاصة بك",
|
||||
"booking_cancel_redirect_uri": "رابط الصفحة التي يمكن للمستخدمين إلغاء حجزهم منها",
|
||||
"booking_reschedule_redirect_uri": "رابط الصفحة التي يمكن للمستخدمين إعادة جدولة حجزهم منها",
|
||||
"booking_conflict_error": "هذا الموعد لم يعد متاحاً. يرجى العودة إلى الصفحة السابقة واختيار وقت آخر.",
|
||||
"open_invitations": "الدعوات المفتوحة",
|
||||
"new_team": "فريق جديد",
|
||||
"create_first_team_and_invite_others": "قم بإنشاء فريقك الأول ودعوة المستخدمين الآخرين للعمل معك.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "تم إنشاء حسابك باستخدام مزود هوية.",
|
||||
"account_managed_by_identity_provider": "تجري إدارة حسابك بواسطة {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "لتغيير بريدك الإلكتروني وكلمة المرور وتمكين المصادقة من عاملين والمزيد، يُرجى زيارة إعدادات حساب {{provider}} لديك.",
|
||||
"account_managed_by_identity_provider_error": "يتم إدارة حسابك بواسطة مزود هوية مختلف. حاول تسجيل الدخول باستخدام {{provider}}.",
|
||||
"user_creation_error": "خطأ في إنشاء مستخدم جديد. يرجى المحاولة مرة أخرى.",
|
||||
"signin_with_google": "تسجيل الدخول عبر Google",
|
||||
"signin_with_saml": "تسجيل الدخول عبر SAML",
|
||||
"signin_with_saml_oidc": "تسجيل الدخول عبر SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "أنت جاهز!",
|
||||
"install_zapier_app": "يرجى تثبيت تطبيق Zapier من App Store أولًا.",
|
||||
"install_make_app": "يرجى تثبيت تطبيق Make من متجر التطبيقات أولًا.",
|
||||
"app_installation": "تثبيت التطبيق",
|
||||
"app_not_installed": "التطبيق غير مثبت",
|
||||
"visit_our_app_store": "عذرًا، هذا التطبيق غير مثبت على حسابك. يرجى زيارة متجر التطبيقات الخاص بنا لاستكشاف واكتشاف هذا وغيره من التطبيقات الرائعة.",
|
||||
"connect_apple_server": "الاتصال بخادم Apple",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "عند إلغاء هذا الحدث",
|
||||
"after_hosts_cal_video_no_show": "بعد عدم انضمام المضيفين إلى فيديو Cal",
|
||||
"after_guests_cal_video_no_show": "بعد عدم انضمام الضيوف إلى فيديو Cal",
|
||||
"join_video_call": "الانضمام إلى مكالمة الفيديو",
|
||||
"sign_in_to_cal_com": "تسجيل الدخول إلى حساب Cal.com الخاص بك",
|
||||
"log_in_to_cal_com": "تسجيل الدخول إلى Cal.com",
|
||||
"track_your_meetings": "تتبع اجتماعاتك، والحصول على إشعارات، وإدارة جدولك بشكل أكثر فعالية.",
|
||||
"choose_how_you_d_like_to_join_call": "اختر كيف ترغب في الانضمام إلى هذه المكالمة",
|
||||
"new_event_trigger": "متى تم حجز الحدث الجديد",
|
||||
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
|
||||
"email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "مخصص",
|
||||
"reminder": "تذكير",
|
||||
"rescheduled": "تمت إعادة الجدولة",
|
||||
"rescheduled_by": "تمت إعادة الجدولة بواسطة",
|
||||
"original_booking": "الحجز الأصلي",
|
||||
"completed": "تمّ",
|
||||
"rating": "التقييم",
|
||||
"reminder_email": "تذكر {{eventType}} مع {{name}} في {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "تم تشغيل {{offOn}} سير العمل {{workflowName}} بنجاح",
|
||||
"download_responses": "تنزيل الردود",
|
||||
"download_responses_description": "تنزيل جميع الردود إلى النموذج بتنسيق CSV.",
|
||||
"view_responses": "عرض الردود",
|
||||
"download": "التنزيل",
|
||||
"downloading": "جاري التنزيل",
|
||||
"download_recording": "تنزيل التسجيل",
|
||||
"transcription_enabled": "التفريغ النصي مفعّل الآن",
|
||||
"transcription_stopped": "التفريغ النصي متوقف الآن",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "إضافة نموذج جديد إلى فريقك",
|
||||
"create_your_first_route": "أنشئ مسارك الأول",
|
||||
"route_to_the_right_person": "التوجيه إلى الشخص المناسب بناءً على إجابات النموذج الخاص بك",
|
||||
"form": "نموذج",
|
||||
"form_description": "قم بإنشاء النموذج الخاص بك لتوجيه صاحب حجز",
|
||||
"copy_link_to_form": "نسخ الرابط إلى النموذج",
|
||||
"theme": "سمة صفحة الحجز",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "رمز التحقق غير صحيح",
|
||||
"not_verified": "لم يتم التحقق منه بعد",
|
||||
"no_availability_in_month": "غير متاح في شهر {{month}}",
|
||||
"no_availability_rolling": "الجدولة متاحة فقط حتى {{days}} مقدماً. يرجى التحقق مرة أخرى قريباً.",
|
||||
"no_availability_range": "انتهت إمكانية الجدولة في {{date}}. يرجى التحقق مرة أخرى قريبًا.",
|
||||
"view_previous_month": "عرض الشهر السابق",
|
||||
"view_next_month": "عرض الشهر التالي",
|
||||
"send_code": "إرسال الرمز",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "لم يعد الدفع لهذا الحدث ممكنًا",
|
||||
"booking_with_payment_cancelled_already_paid": "استرداد المبلغ المدفوع لهذا الحجز قيد التنفيذ.",
|
||||
"booking_with_payment_cancelled_refunded": "تم استرداد مبلغ هذا الحجز.",
|
||||
"booking_with_payment_cancelled_no_refund": "وفقًا لسياسة استرداد الأموال للفعالية، فإن دفعة الحجز غير قابلة للاسترداد.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "انتهت فترة استرداد الأموال للفعالية. وبالتالي، دفعة الحجز غير قابلة للاسترداد.",
|
||||
"booking_confirmation_failed": "فشل تأكيد الحجز",
|
||||
"not_enough_seats": "لا توجد مقاعد كافية",
|
||||
"form_builder_field_already_exists": "يوجد حقل بهذا الاسم بالفعل",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "افتح توافر المستخدمين",
|
||||
"organization_no_slots_notification_switch_title": "احصل على إشعارات عندما لا يكون لدى فريقك توافر",
|
||||
"organization_no_slots_notification_switch_description": "سيحصل المسؤولون على إشعارات عبر البريد الإلكتروني عندما يحاول مستخدم حجز عضو في الفريق ويواجه 'عدم التوافر'. نقوم بإرسال هذا البريد الإلكتروني بعد حدوث حالتين ونذكركم كل 7 أيام لكل مستخدم.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "تعطيل إشعارات الرسائل القصيرة لأنواع الفعاليات التي تعتمد على الهاتف فقط",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "تعطيل إشعارات الرسائل القصيرة التلقائية لأنواع الفعاليات التي تتطلب رقم الهاتف فقط (attendeePhoneNumber) كسؤال إلزامي مع البريد الإلكتروني كخيار اختياري أو غير مطلوب",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} أضافك إلى المنظمة {{team}} على {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} دعاك للانضمام إلى المنظمة {{team}} على {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} أضافك إلى الفريق {{team}} من المنظمة {{parentTeamName}} على {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "تم تغيير رابطك من {{a0}} إلى {{a1}} ولكن لا تقلق، جميع الروابط السابقة لا تزال تعمل وتعيد التوجيه بشكل مناسب. <br /><br />يرجى ملاحظة: تم نقل جميع أنواع الأحداث الشخصية الخاصة بك إلى مؤسسة <strong>{{teamName}}</strong>، والتي قد تشمل أيضًا رابطًا شخصيًا محتملاً.<br /><br />يرجى تسجيل الدخول والتأكد من عدم وجود أحداث خاصة في حسابك المؤسسي الجديد.<br /><br />للأحداث الشخصية، نوصي بإنشاء حساب جديد باستخدام عنوان بريد إلكتروني شخصي.<br /><br />استمتع برابطك النظيف الجديد: {{a2}}",
|
||||
"email_organization_created|subject": "تم إنشاء مؤسستك",
|
||||
"your_current_plan": "خطتك الحالية",
|
||||
"organization_price_per_user_month": "37 دولارًا لكل مستخدم شهريًا (بحد أدنى 30 مقعدًا)",
|
||||
"organization_price_per_user_month": "37$ لكل مستخدم شهريًا",
|
||||
"privacy_organization_description": "إدارة إعدادات الخصوصية لمؤسستك",
|
||||
"privacy": "الخصوصية",
|
||||
"team_will_be_under_org": "الفرق الجديدة ستكون تحت مؤسستك",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "بالمتابعة، فإنك توافق على",
|
||||
"terms": "الشروط",
|
||||
"always_show_x_days": "دائمًا {{x}} أيام متاحة",
|
||||
"team_subscription_cancelled_successfully": "تم إلغاء اشتراك الفريق بنجاح",
|
||||
"team_subscription_cancellation_error": "حدث خطأ أثناء إلغاء اشتراك الفريق",
|
||||
"unable_to_subscribe_to_the_platform": "حدث خطأ أثناء محاولة الاشتراك في خطة المنصة، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"updating_oauth_client_error": "حدث خطأ أثناء تحديث عميل OAuth، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"creating_oauth_client_error": "حدث خطأ أثناء إنشاء عميل OAuth، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "تخطي إنشاء سجل {{entry}} إذا لم يكن موجودًا في Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "إذا لم تكن جهة الاتصال موجودة تحت حساب، قم بإنشاء عميل محتمل جديد من المشارك",
|
||||
"salesforce_create_new_contact_under_account": "إنشاء جهة اتصال جديدة تحت حساب بناءً على نطاق البريد الإلكتروني للمشارك وجهات الاتصال الموجودة",
|
||||
"salesforce_change_record_owner_on_booking": "تغيير مالك السجل عند الحجز",
|
||||
"mass_assign_attributes": "تعيين السمات بشكل جماعي",
|
||||
"reroute_preview_custom_message": "ينتج عنه عرض رسالة مخصصة. حاول تغيير الاستجابة لتوجيه إلى حدث",
|
||||
"reroute_preview_external_redirect": "ينتج عنه إعادة التوجيه إلى {{externalUrl}}. حاول تغيير الاستجابة لتوجيه إلى حدث",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "تم التوجيه إلى كل فترة",
|
||||
"per_day": "لكل يوم",
|
||||
"per_week": "لكل أسبوع",
|
||||
"per_month": "لكل شهر",
|
||||
"per_month": "شهريًا",
|
||||
"routing_form_insights_assignment_reason": "سبب التعيين",
|
||||
"access_denied": "تم رفض الوصول",
|
||||
"salesforce_route_to_owner": "سيكون مالك جهة الاتصال هو مضيف Round Robin إذا كان متاحاً",
|
||||
"salesforce_add_attendees_as": "إضافة الحاضرين الجدد كـ",
|
||||
"salesforce_do_not_route_to_owner": "لن يتم فرض مالك جهة الاتصال (يمكن أن يظل مضيفاً إذا تطابق مع السمات ومعايير Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "التوجيه إلى مستخدم يطابق حقل البحث في الحساب",
|
||||
"salesforce_option": "خيار Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "العجز",
|
||||
"routing_form": "نموذج التوجيه",
|
||||
"go_back_and_save": "العودة والحفظ",
|
||||
"save_changes": "حفظ التغييرات",
|
||||
"leave_without_saving": "المغادرة دون حفظ",
|
||||
"leave_without_saving_description": "هل أنت متأكد من أنك تريد المغادرة دون حفظ التغييرات في نموذج التوجيه الخاص بك؟",
|
||||
"something_unexpected_occurred": "حدث خطأ غير متوقع",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "تفويض",
|
||||
"next": "التالي",
|
||||
"hide": "إخفاء",
|
||||
"show": "عرض",
|
||||
"utm_params": "معلمات UTM",
|
||||
"no_utm_params": "لا توجد معلمات UTM متاحة.",
|
||||
"asc": "تصاعدي",
|
||||
"desc": "تنازلي",
|
||||
"verify_email_change": "تأكيد تغيير البريد الإلكتروني",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "تحتاج إلى الحد الأدنى من الفرق المنشورة",
|
||||
"you_are_part_of_this_organization_already": "أنت بالفعل جزء من هذه المؤسسة",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "أنت جزء من مؤسسة أخرى، لا يمكنك إنشاء مؤسسة جديدة",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "أنت جزء من مؤسسة منصة أخرى، لا يمكنك إنشاء مؤسسة جديدة",
|
||||
"organization_payment_success": "نجاح دفع المؤسسة",
|
||||
"organization_payment_success_description": "تم إنشاء مؤسستك بنجاح",
|
||||
"this_may_take_a_few_seconds": "قد يستغرق هذا بضع ثوانٍ...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "تم إكمال تأهيل المؤسسة بالفعل",
|
||||
"organization_onboarding_already_exists": "تأهيل المؤسسة موجود بالفعل",
|
||||
"organization_onboarding_not_found": "لم يتم العثور على تأهيل المؤسسة",
|
||||
"payment_successful": "تم الدفع بنجاح",
|
||||
"payment_successful": "تمت عملية الدفع بنجاح!",
|
||||
"handover_onboarding_page_title": "تسليم عملية التأهيل",
|
||||
"handover_onboarding_page_description": "تسليم عملية التأهيل للمستخدم",
|
||||
"organization_already_exists_with_this_slug": "المؤسسة موجودة بالفعل بهذا الاسم المختصر",
|
||||
@@ -3022,6 +3061,9 @@
|
||||
"tip_username_plus": "نصيحة: يمكنك إضافة '+' بين أسماء المستخدمين: cal.com/anna+brian لإنشاء اجتماع جماعي ديناميكي",
|
||||
"user_has_no_team_yet": "ليس لديك فريق بعد",
|
||||
"no_team_members": "ليس لديك أعضاء في الفريق بعد",
|
||||
"recurring_event_doesnt_support_seats": "الفعالية المتكررة لا تدعم ميزة المقاعد. اجعلها غير متكررة لتمكين المقاعد.",
|
||||
"seats_doesnt_support_recurring": "ميزة المقاعد لا تدعم الفعاليات المتكررة. قم بتعطيل ميزة المقاعد لجعلها متكررة.",
|
||||
"recurring_event_seats_error": "الفعالية المتكررة لا تدعم ميزة المقاعد. قم بتعطيل ميزة المقاعد أو اجعل الفعالية غير متكررة.",
|
||||
"segment": "شريحة",
|
||||
"rename": "إعادة تسمية",
|
||||
"rename_segment": "إعادة تسمية الشريحة",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "الحجوزات الأكثر إلغاءً",
|
||||
"name_or_email": "الاسم أو البريد الإلكتروني",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "إذا لم يتم العثور على جهة اتصال، يتم الرجوع إلى مالك العميل المحتمل إذا كان موجودًا",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ أضف السلاسل الجديدة أعلاه هنا ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "التاريخ والوقت",
|
||||
"email_reminder_upcoming_event_notice" : "هذا تذكير بالحدث القادم.",
|
||||
"email_reminder_triggered_by_workflow" : "تم تشغيل هذا التذكير بواسطة سير العمل في Cal.",
|
||||
"enable_delegation_credential": "تمكين بيانات اعتماد التفويض",
|
||||
"enable_delegation_credential_description": "امنح Cal.com وصولاً تلقائيًا إلى تقويمات جميع أعضاء المؤسسة من خلال تمكين بيانات اعتماد التفويض.",
|
||||
"disable_delegation_credential": "تعطيل بيانات اعتماد التفويض",
|
||||
"disable_delegation_credential_description": "بمجرد تعطيل بيانات اعتماد التفويض، سيحتاج أعضاء المؤسسة الذين لم يقوموا بربط تقويماتهم إلى القيام بذلك يدويًا.",
|
||||
"last_active": "آخر نشاط",
|
||||
"member_since": "عضو منذ",
|
||||
"last_updated": "آخر تحديث",
|
||||
"salesforce_on_cancel_write_to_event": "عند إلغاء الحجز، اكتب في سجل الحدث بدلاً من حذف الحدث",
|
||||
"salesforce_on_every_cancellation": "عند كل إلغاء",
|
||||
"report_issue": "الإبلاغ عن مشكلة",
|
||||
"report_issue_description": "يمكنك تقديم تذكرة على GitHub أو ترقية خطتك لتلقي دعم فوري مع مؤتمرات المطورين",
|
||||
"open_issue": "فتح مشكلة",
|
||||
"this_is_your_current_plan": "هذه هي خطتك الحالية",
|
||||
"schedule_a_time": "جدولة وقت",
|
||||
"this_includes": "هذا يشمل:",
|
||||
"oauth_client_updated_successfully": "تم تحديث عميل OAuth بنجاح",
|
||||
"oauth_client_not_found": "لم يتم العثور على عميل OAuth",
|
||||
"subscribe_to_platform": "الاشتراك في المنصة",
|
||||
"error_accessing_webhooks": "حدث خطأ أثناء محاولة الوصول إلى الويب هوكس",
|
||||
"webhook_update_failed": "فشل تحديث الويب هوك",
|
||||
"webhook_create_failed": "فشل إنشاء الويب هوك",
|
||||
"invalid_link": "رابط غير صالح",
|
||||
"currently_subscribed_to_plan": "أنت مشترك حالياً في خطة {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "المستخدم/الفريق",
|
||||
"client_id_copied": "تم نسخ معرف العميل!",
|
||||
"client_secret_copied": "تم نسخ سر العميل!",
|
||||
"maintenance_message": "يقوم فريق Cal.com بإجراء صيانة مجدولة. إذا كان لديك أي أسئلة، يرجى الاتصال بالدعم.",
|
||||
"your_payment_failed": "فشلت عملية الدفع الخاصة بك",
|
||||
"check_your_inbox": "تحقق من صندوق الوارد الخاص بك",
|
||||
"account_created_premium_not_reserved": "تم إنشاء حسابك، ولكن لم يتم حجز اسم المستخدم المميز الخاص بك.",
|
||||
"email_sent_with_activation_link": "لقد أرسلنا بريدًا إلكترونيًا إلى {{email}} يحتوي على رابط لتفعيل حسابك.",
|
||||
"activate_account_to_purchase_username": "بمجرد تفعيل حسابك، ستتمكن من محاولة شراء اسم المستخدم المميز الخاص بك مرة أخرى أو اختيار اسم آخر.",
|
||||
"open_in_gmail": "فتح في Gmail",
|
||||
"dont_see_email": "لم تستلم بريدًا إلكترونيًا؟",
|
||||
"resend_in_seconds": "إعادة الإرسال خلال {{seconds}} ثانية",
|
||||
"resend": "إعادة الإرسال",
|
||||
"verification_email_sent": "تم إرسال بريد التحقق",
|
||||
"select_all_members": "اختيار جميع الأعضاء",
|
||||
"select_all_members_tooltip": "سيؤدي اختيار جميع الأعضاء إلى إضافة جميع أعضاء الفريق المستقبليين عند إضافتهم إلى الفريق.",
|
||||
"form_settings": "إعدادات النموذج",
|
||||
"remove_whitelist_status": "إزالة حالة القائمة البيضاء",
|
||||
"whitelist_user_workflows": "إضافة سير عمل المستخدم إلى القائمة البيضاء",
|
||||
"user_workflows_whitelisted": "تمت إضافة سير عمل المستخدم إلى القائمة البيضاء",
|
||||
"user_workflows_unwhitelisted": "تمت إزالة سير عمل المستخدم من القائمة البيضاء",
|
||||
"date_and_time": "التاريخ والوقت",
|
||||
"email_reminder_upcoming_event_notice": "هذا تذكير بالحدث القادم.",
|
||||
"email_reminder_triggered_by_workflow": "تم تشغيل هذا التذكير بواسطة سير العمل في Cal.",
|
||||
"event_upper_case": "حدث",
|
||||
"scheduling_by": "جدولة بواسطة",
|
||||
"experience_review_prompt": "كيف كانت تجربتك الأخيرة؟",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "ما مدى رضاك عن اجتماعك الأخير؟",
|
||||
"meeting_not_joined_question": "لم تحضر الاجتماع؟",
|
||||
"reschedule_cta_short": "أعد الجدولة من هنا",
|
||||
"hide_organizer_email": "إخفاء البريد الإلكتروني للمنظم",
|
||||
"platform_customer_cant_create_organization": "أنت بالفعل جزء من منظمة منصة ولهذا السبب لا يمكنك إنشاء منظمة جديدة. يمكن لكل مستخدم الانتماء إلى منظمة واحدة فقط. يرجى إنشاء حساب cal.com جديد ببريد إلكتروني مختلف واستخدام هذا الحساب للاشتراك في خطة المنظمات.",
|
||||
"organization_customer_cant_create_platform": "أنت بالفعل جزء من منظمة ولهذا السبب لا يمكنك إنشاء منظمة منصة. يمكن لكل مستخدم الانتماء إلى منظمة واحدة فقط. يرجى إنشاء حساب cal.com جديد ببريد إلكتروني مختلف واستخدام هذا الحساب للاشتراك في خطة المنصة.",
|
||||
"hide_organizer_email_description": "إخفاء عنوان البريد الإلكتروني للمنظم من شاشة الحجز وإشعارات البريد الإلكتروني وأحداث التقويم",
|
||||
"you_and_conjunction": "& أنت",
|
||||
"email_survey_triggered_by_workflow": "تم تشغيل هذا الاستبيان بواسطة سير العمل في كال."
|
||||
"select_verified_email": "اختر بريدًا إلكترونيًا تم التحقق منه",
|
||||
"custom_reply_to_email_title": "بريد إلكتروني مخصص للرد",
|
||||
"custom_reply_to_email_description": "استخدم عنوان بريد إلكتروني مختلف كعنوان للرد على رسائل التأكيد بدلاً من بريد المنظم",
|
||||
"email_survey_triggered_by_workflow": "تم تشغيل هذا الاستبيان بواسطة سير العمل في كال.",
|
||||
"skip_trial": "تخطي الفترة التجريبية",
|
||||
"team_trials_skipped_successfully": "تم تخطي الفترات التجريبية للفريق بنجاح",
|
||||
"sms_workflow_consent": "بإدخال رقم هاتفك، فإنك توافق على تلقي رسائل SMS لهذا الحدث. قد تطبق رسوم على رسائل SMS.",
|
||||
"routing_preview_more_info_found_insights": "يمكن العثور على مزيد من المعلومات في <0>رؤى التوجيه</0>",
|
||||
"results": "النتائج",
|
||||
"view_form": "عرض النموذج",
|
||||
"sms_opt_out_message": "أرسل STOP للإلغاء من رسائل SMS",
|
||||
"routing_form_next_in_queue": "{{count}} التالي في قائمة الانتظار",
|
||||
"routing_form_select_members_to_email": "إرسال ردود البريد الإلكتروني إلى",
|
||||
"routing_incomplete_booking_tab": "الحجوزات غير المكتملة",
|
||||
"include_no_show_in_rr_calculation": "تضمين الحجوزات التي لم تظهر في حسابات round robin",
|
||||
"matching": "المطابقة",
|
||||
"event_redirect": "إعادة توجيه الحدث",
|
||||
"reset_form": "إعادة تعيين النموذج",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ أضف السلاسل الجديدة أعلاه هنا ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Tam adınız",
|
||||
"no_name": "Ad yoxdur",
|
||||
"enter_number_between_range": "Zəhmət olmasa 1 ilə {{maxOccurences}} arasında bir rəqəm daxil edin",
|
||||
"continue_as_guest_description": "Sürətli və asan - hesab tələb olunmur. Birdəfəlik görüşlər üçün idealdır.",
|
||||
"email_address": "E-poçt ünvanı",
|
||||
"enter_valid_email": "Zəhmət olmasa etibarlı bir e-poçt ünvanı daxil edin",
|
||||
"please_schedule_future_call": "Zəhmət olmasa {{seconds}} saniyə ərzində mövcud deyilsə, gələcək bir zəng planlaşdırın",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Şəxsi (İştirakçının ünvanı)",
|
||||
"somewhere_else": "Başqa yerdə",
|
||||
"custom_attendee_location": "Xüsusi iştirakçı yeri",
|
||||
"continue_as_guest": "Qonaq kimi davam et",
|
||||
"any_location": "Hər hansı bir yer",
|
||||
"yes": "Bəli",
|
||||
"no": "Xeyr",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Komanda uğurla yeniləndi",
|
||||
"your_team_updated_successfully": "Komandanız uğurla yeniləndi.",
|
||||
"your_org_updated_successfully": "Təşkilatınız uğurla yeniləndi.",
|
||||
"error_copying_to_clipboard": "Mübadilə buferinə kopyalamada xəta",
|
||||
"about": "Haqqında",
|
||||
"team_description": "Komandanız haqqında bir neçə cümlə. Bu, komandanızın URL səhifəsində görünəcək.",
|
||||
"organization_id": "Təşkilat ID",
|
||||
"organization_id_copied": "Təşkilat ID kopyalandı.",
|
||||
"org_description": "Təşkilatınız haqqında bir neçə cümlə. Bu, təşkilatınızın URL səhifəsində görünəcək.",
|
||||
"team_id": "Komanda ID",
|
||||
"team_id_copied": "Komanda ID kopyalandı.",
|
||||
"members": "Üzvlər",
|
||||
"organization_members": "Təşkilat üzvləri",
|
||||
"member": "Üzv",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Bu üzvü komandadan çıxarmaq istədiyinizə əminsinizmi?",
|
||||
"confirm_disband_team": "Bəli, komandayı ləğv et",
|
||||
"confirm_remove_member": "Bəli, üzvü çıxar",
|
||||
"confirm_subscription_cancellation": "Bəli, abunəliyi ləğv et",
|
||||
"cancel_subscription": "Abunəliyi ləğv et",
|
||||
"cancel_subscription_description": "Abunəliyinizi ləğv etmək cari planınızı daimi olaraq deaktiv edəcək. Bu əməliyyat geri qaytarıla bilməz.",
|
||||
"remove_member": "Üzvü çıxar",
|
||||
"manage_your_team": "Komandanızı idarə edin",
|
||||
"no_teams": "Hələ heç bir komandanız yoxdur.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "Rezervasiya səhifənizin URL-i",
|
||||
"booking_cancel_redirect_uri": "İstifadəçilərinizin rezervasiyanı ləğv edə biləcəyi səhifənin URL-i",
|
||||
"booking_reschedule_redirect_uri": "İstifadəçilərinizin rezervasiyanı yenidən planlaşdıra biləcəyi səhifənin URL-i",
|
||||
"booking_conflict_error": "Bu vaxt artıq mövcud deyil. Zəhmət olmasa əvvəlki səhifəyə qayıdın və başqa vaxt seçin.",
|
||||
"open_invitations": "Açıq Dəvətlər",
|
||||
"new_team": "Yeni Komanda",
|
||||
"create_first_team_and_invite_others": "İlk komandanızı yaradın və digər istifadəçiləri əməkdaşlığa dəvət edin.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Hesabınız bir Kimlik Sağlayıcı istifadə edilərək yaradılıb.",
|
||||
"account_managed_by_identity_provider": "Hesabınız {{provider}} tərəfindən idarə olunur",
|
||||
"account_managed_by_identity_provider_description": "E-poçtunuzu, şifrənizi dəyişmək, iki faktorlu autentifikasiyanı aktivləşdirmək və daha çox şey üçün, zəhmət olmasa {{provider}} hesab ayarlarınıza daxil olun.",
|
||||
"account_managed_by_identity_provider_error": "Hesabınız fərqli kimlik təminatçısı tərəfindən idarə olunur. {{provider}} ilə daxil olmağı sınayın.",
|
||||
"user_creation_error": "Yeni istifadəçi yaratmada xəta. Zəhmət olmasa yenidən cəhd edin.",
|
||||
"signin_with_google": "Google ilə daxil olun",
|
||||
"signin_with_saml": "SAML ilə daxil olun",
|
||||
"signin_with_saml_oidc": "SAML/OIDC ilə daxil olun",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Hazırsınız!",
|
||||
"install_zapier_app": "Zəhmət olmasa əvvəlcə Zapier Tətbiqini tətbiq mağazasında quraşdırın.",
|
||||
"install_make_app": "Zəhmət olmasa əvvəlcə Make Tətbiqini tətbiq mağazasında quraşdırın.",
|
||||
"app_installation": "Tətbiq Quraşdırması",
|
||||
"app_not_installed": "Tətbiq quraşdırılmayıb",
|
||||
"visit_our_app_store": "Bağışlayın, bu tətbiq hesabınızda quraşdırılmayıb. Zəhmət olmasa tətbiq mağazamızı ziyarət edin və bu və digər əla tətbiqləri kəşf edin.",
|
||||
"connect_apple_server": "Apple Serverinə qoşulun",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "tədbir ləğv edildikdə",
|
||||
"after_hosts_cal_video_no_show": "Təşkilatçılar Cal video görüşünə qoşulmadıqdan sonra",
|
||||
"after_guests_cal_video_no_show": "Qonaqlar Cal video görüşünə qoşulmadıqdan sonra",
|
||||
"join_video_call": "Video zəngə qoşulun",
|
||||
"sign_in_to_cal_com": "Cal.com hesabınıza daxil olun",
|
||||
"log_in_to_cal_com": "Cal.com-a daxil olun",
|
||||
"track_your_meetings": "Görüşlərinizi izləyin, bildirişlər alın və cədvəlinizi daha effektiv idarə edin.",
|
||||
"choose_how_you_d_like_to_join_call": "Bu zəngə necə qoşulmaq istədiyinizi seçin",
|
||||
"new_event_trigger": "yeni tədbir sifariş edildikdə",
|
||||
"email_host_action": "ev sahibinə e-poçt göndərin",
|
||||
"email_attendee_action": "iştirakçılara e-poçt göndərin",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Fərdi",
|
||||
"reminder": "Xatırlatma",
|
||||
"rescheduled": "Yenidən planlaşdırıldı",
|
||||
"rescheduled_by": "Tərəfindən yenidən planlaşdırıldı",
|
||||
"original_booking": "Orijinal rezervasiya",
|
||||
"completed": "Tamamlandı",
|
||||
"rating": "Reytinq",
|
||||
"reminder_email": "Xatırlatma: {{eventType}} {{name}} ilə {{date}} tarixində",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}} iş axını uğurla {{offOn}} edildi",
|
||||
"download_responses": "Cavabları yüklə",
|
||||
"download_responses_description": "Formunuza verilən bütün cavabları CSV formatında yükləyin.",
|
||||
"view_responses": "Cavablara baxın",
|
||||
"download": "Yüklə",
|
||||
"downloading": "Yüklənir",
|
||||
"download_recording": "Qeydi yüklə",
|
||||
"transcription_enabled": "Transkripsiyalar indi aktivdir",
|
||||
"transcription_stopped": "Transkripsiyalar dayandırıldı",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Komandanıza yeni forma əlavə edin",
|
||||
"create_your_first_route": "İlk marşrutunuzu yaradın",
|
||||
"route_to_the_right_person": "Formunuza verdiyiniz cavablara əsasən düzgün şəxsə yönləndirin",
|
||||
"form": "Form",
|
||||
"form_description": "Rezervasiya edən şəxsi yönləndirmək üçün formanızı yaradın",
|
||||
"copy_link_to_form": "Formanın linkini kopyalayın",
|
||||
"theme": "Rezervasiya səhifəsinin teması",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Yanlış təsdiq kodu",
|
||||
"not_verified": "Hələ təsdiqlənməyib",
|
||||
"no_availability_in_month": "{{month}} ayında əlçatanlıq yoxdur",
|
||||
"no_availability_rolling": "Planlaşdırma yalnız {{days}} gün əvvəlcədən mümkündür. Zəhmət olmasa tezliklə yenidən yoxlayın.",
|
||||
"no_availability_range": "Planlaşdırma {{date}} tarixində başa çatdı. Zəhmət olmasa, tezliklə yenidən yoxlayın.",
|
||||
"view_previous_month": "Əvvəlki aya baxın",
|
||||
"view_next_month": "Növbəti aya bax",
|
||||
"send_code": "Kodu göndər",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Bu tədbir üçün ödəniş artıq mümkün deyil",
|
||||
"booking_with_payment_cancelled_already_paid": "Bu rezervasiya ödənişi üçün geri ödəmə yoldadır.",
|
||||
"booking_with_payment_cancelled_refunded": "Bu rezervasiya ödənişi geri ödənilib.",
|
||||
"booking_with_payment_cancelled_no_refund": "Tədbirin geri ödəmə siyasətinə əsasən, rezervasiya ödənişi geri qaytarılmır.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Tədbirin geri ödəmə müddəti başa çatıb. Buna görə də, rezervasiya ödənişi geri qaytarılmır.",
|
||||
"booking_confirmation_failed": "Rezervasiya təsdiqi uğursuz oldu",
|
||||
"not_enough_seats": "Kifayət qədər oturacaq yoxdur",
|
||||
"form_builder_field_already_exists": "Bu adla bir sahə artıq mövcuddur",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "İstifadəçilərin mövcudluğunu açın",
|
||||
"organization_no_slots_notification_switch_title": "Komandanızın mövcudluğu olmadıqda bildirişlər alın",
|
||||
"organization_no_slots_notification_switch_description": "İstifadəçi komanda üzvünü rezervasiya etməyə çalışdıqda və 'Mövcudluq yoxdur' ilə qarşılaşdıqda administratorlar e-poçt bildirişləri alacaqlar. Bu e-poçtu iki hadisədən sonra tetikleyirik və hər istifadəçi üçün hər 7 gündə bir xatırladırıq.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Yalnız telefon tədbirləri üçün SMS bildirişlərini deaktiv edin",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Yalnız telefon nömrəsi (attendeePhoneNumber) tələb olunan sual kimi, e-poçt isə istəyə bağlı və ya tələb olunmayan tədbir növləri üçün avtomatik SMS bildirişlərini deaktiv edin",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} sizi {{appName}} üzərində {{team}} təşkilatına əlavə etdi",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} sizi {{appName}} üzərində {{team}} təşkilatına qoşulmağa dəvət etdi",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} sizi {{appName}} üzərində {{parentTeamName}} təşkilatının {{team}} komandasına əlavə etdi",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Linkiniz {{a0}}-dan {{a1}}-a dəyişdirilib, lakin narahat olmayın, bütün əvvəlki linklər hələ də işləyir və müvafiq şəkildə yönləndirilir. <br /><br />Qeyd edək ki: Bütün şəxsi tədbir növləriniz <strong>{{teamName}}</strong> təşkilatına köçürülüb, bura potensial şəxsi link də daxil ola bilər.<br /><br />Zəhmət olmasa daxil olun və yeni təşkilat hesabınızda şəxsi tədbirlərinizin olmadığından əmin olun.<br /><br />Şəxsi tədbirlər üçün şəxsi e-poçt ünvanı ilə yeni hesab yaratmağı tövsiyə edirik.<br /><br />Yeni təmiz linkinizin keyfini çıxarın: {{a2}}",
|
||||
"email_organization_created|subject": "Təşkilatınız yaradıldı",
|
||||
"your_current_plan": "Cari planınız",
|
||||
"organization_price_per_user_month": "Hər istifadəçi üçün ayda 37 dollar (minimum 30 yer)",
|
||||
"organization_price_per_user_month": "Ayda istifadəçi başına $37",
|
||||
"privacy_organization_description": "Təşkilatınız üçün məxfilik parametrlərini idarə edin",
|
||||
"privacy": "Məxfilik",
|
||||
"team_will_be_under_org": "Yeni komandalar təşkilatınızın tərkibində olacaq",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Davam etməklə, bizim",
|
||||
"terms": "Şərtlər",
|
||||
"always_show_x_days": "Həmişə {{x}} gün mövcuddur",
|
||||
"team_subscription_cancelled_successfully": "Komanda abunəliyi uğurla ləğv edildi",
|
||||
"team_subscription_cancellation_error": "Komanda abunəliyini ləğv edərkən xəta baş verdi",
|
||||
"unable_to_subscribe_to_the_platform": "Platforma planına abunə olmağa çalışarkən bir səhv baş verdi, zəhmət olmasa bir az sonra yenidən cəhd edin",
|
||||
"updating_oauth_client_error": "OAuth müştərisini yeniləyərkən bir səhv baş verdi, zəhmət olmasa bir az sonra yenidən cəhd edin",
|
||||
"creating_oauth_client_error": "OAuth müştərisi yaradılarkən bir səhv baş verdi, zəhmət olmasa bir az sonra yenidən cəhd edin",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Əgər {{entry}} Salesforce-da mövcud deyilsə, qeyd yaratmağı keçin",
|
||||
"salesforce_if_account_does_not_exist": "Əgər əlaqə hesab altında mövcud deyilsə, iştirakçıdan yeni potensial müştəri yaradın",
|
||||
"salesforce_create_new_contact_under_account": "İştirakçının email domeni və mövcud əlaqələr əsasında hesab altında yeni əlaqə yaradın",
|
||||
"salesforce_change_record_owner_on_booking": "Rezervasiya zamanı qeyd sahibini dəyişdirin",
|
||||
"mass_assign_attributes": "Atributları kütləvi təyin et",
|
||||
"reroute_preview_custom_message": "Bu, xüsusi mesajın göstərilməsi ilə nəticələnir. Cavabı bir tədbir üçün marşruta dəyişdirməyə çalışın",
|
||||
"reroute_preview_external_redirect": "Bu, {{externalUrl}} ünvanına yönləndirmə ilə nəticələnir. Cavabı bir tədbir üçün marşruta dəyişdirməyə çalışın",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Dövr üzrə yönləndirilmə",
|
||||
"per_day": "Gün üzrə",
|
||||
"per_week": "Həftə üzrə",
|
||||
"per_month": "Ay üzrə",
|
||||
"per_month": "aylıq",
|
||||
"routing_form_insights_assignment_reason": "Təyin edilmə səbəbi",
|
||||
"access_denied": "Giriş qadağandır",
|
||||
"salesforce_route_to_owner": "Əlaqə sahibi mövcud olduqda Round Robin ev sahibi olacaq",
|
||||
"salesforce_add_attendees_as": "Yeni iştirakçıları belə əlavə edin",
|
||||
"salesforce_do_not_route_to_owner": "Əlaqə sahibi məcbur edilməyəcək (əgər atributlara və Round Robin meyarlarına uyğun gəlirsə, yenə də ev sahibi ola bilər)",
|
||||
"salesforce_route_to_custom_lookup_field": "Hesabda axtarış sahəsinə uyğun gələn istifadəçiyə yönləndir",
|
||||
"salesforce_option": "Salesforce Seçimi",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Çatışmazlıq",
|
||||
"routing_form": "Marşrutlama forması",
|
||||
"go_back_and_save": "Geri qayıt və yadda saxla",
|
||||
"save_changes": "Dəyişiklikləri saxla",
|
||||
"leave_without_saving": "Yadda saxlamadan çıx",
|
||||
"leave_without_saving_description": "Marşrutlaşdırma formanızdakı dəyişiklikləri yadda saxlamadan çıxmaq istədiyinizə əminsiniz?",
|
||||
"something_unexpected_occurred": "Gözlənilməz bir xəta baş verdi",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "İcazə ver",
|
||||
"next": "Növbəti",
|
||||
"hide": "Gizlət",
|
||||
"show": "Göstər",
|
||||
"utm_params": "UTM parametrləri",
|
||||
"no_utm_params": "UTM parametrləri mövcud deyil.",
|
||||
"asc": "Artan",
|
||||
"desc": "Azalan",
|
||||
"verify_email_change": "E-poçt dəyişikliyini təsdiqlə",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Minimum sayda dərc edilmiş komandalarınız olmalıdır",
|
||||
"you_are_part_of_this_organization_already": "Siz artıq bu təşkilatın üzvüsünüz",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Siz başqa bir təşkilatın üzvüsünüz, yeni təşkilat yarada bilməzsiniz",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Siz başqa bir platforma təşkilatının üzvüsünüz, yeni təşkilat yarada bilməzsiniz",
|
||||
"organization_payment_success": "Təşkilat ödənişi uğurludur",
|
||||
"organization_payment_success_description": "Təşkilatınız uğurla yaradılıb",
|
||||
"this_may_take_a_few_seconds": "Bu bir neçə saniyə çəkə bilər...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Təşkilat qeydiyyatı artıq tamamlanıb",
|
||||
"organization_onboarding_already_exists": "Təşkilat qeydiyyatı artıq mövcuddur",
|
||||
"organization_onboarding_not_found": "Təşkilat qeydiyyatı tapılmadı",
|
||||
"payment_successful": "Ödəniş uğurlu oldu",
|
||||
"payment_successful": "Ödəniş uğurlu oldu!",
|
||||
"handover_onboarding_page_title": "Qeydiyyatın təhvil verilməsi",
|
||||
"handover_onboarding_page_description": "İstifadəçiyə qeydiyyatın təhvil verilməsi",
|
||||
"organization_already_exists_with_this_slug": "Bu slug ilə təşkilat artıq mövcuddur",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Link",
|
||||
"rows_per_page": "səhifə başına sətir",
|
||||
"pagination_status": "{{totalItems}} içərisindən {{currentRange}}",
|
||||
"tip_username_plus": "Məsləhət: Dinamik qrup görüşü yaratmaq üçün istifadəçi adları arasında '+' işarəsi istifadə edə bilərsiniz: cal.com/anna+brian",
|
||||
"tip_username_plus": "Məsləhət: İstifadəçi adları arasında '+' əlavə edə bilərsiniz: cal.com/anna+brian dinamik qrup görüşü yaratmaq üçün",
|
||||
"user_has_no_team_yet": "Hələ komandanız yoxdur",
|
||||
"no_team_members": "Hələ komanda üzvləriniz yoxdur",
|
||||
"recurring_event_doesnt_support_seats": "Təkrarlanan tədbir yerlər funksiyasını dəstəkləmir. Yerləri aktivləşdirmək üçün onu təkrarlanmayan edin.",
|
||||
"seats_doesnt_support_recurring": "Yerlər funksiyası təkrarlanan tədbiri dəstəkləmir. Təkrarlanma funksiyasını aktivləşdirmək üçün yerlər funksiyasını deaktiv edin.",
|
||||
"recurring_event_seats_error": "Təkrarlanan tədbir yerlər funksiyasını dəstəkləmir. Yerlər funksiyasını deaktiv edin və ya tədbiri təkrarlanmayan edin.",
|
||||
"segment": "Seqment",
|
||||
"rename": "Adını dəyişdir",
|
||||
"rename_segment": "Seqmentin adını dəyişdir",
|
||||
@@ -3053,16 +3095,82 @@
|
||||
"most_cancelled_bookings": "Ən çox ləğv edilmiş rezervasiyalar",
|
||||
"name_or_email": "Ad və ya E-poçt",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Əgər əlaqə tapılmazsa, mövcud olduğu təqdirdə potensial müştəri sahibinə qayıt",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Yeni sətirləri bura əlavə edin ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Tarix & Saat",
|
||||
"email_reminder_upcoming_event_notice" : "Bu, qarşıdan gələn tədbiriniz haqqında xatırlatmadır.",
|
||||
"email_reminder_triggered_by_workflow" : "Bu xatırladıcı Calda iş axını ilə işə salınıb.",
|
||||
"enable_delegation_credential": "Nümayəndəlik etimadnaməsini aktivləşdirin",
|
||||
"enable_delegation_credential_description": "Nümayəndəlik etimadnaməsini aktivləşdirməklə Cal.com-a bütün təşkilat üzvlərinin təqvimlərinə avtomatik giriş imkanı verin.",
|
||||
"disable_delegation_credential": "Nümayəndəlik etimadnaməsini deaktiv edin",
|
||||
"disable_delegation_credential_description": "Nümayəndəlik etimadnaməsi deaktiv edildikdən sonra, təqvimlərini qoşmamış təşkilat üzvləri bunu əl ilə etməli olacaqlar.",
|
||||
"last_active": "Son aktivlik",
|
||||
"member_since": "Üzvlük tarixi",
|
||||
"last_updated": "Son yenilənmə",
|
||||
"salesforce_on_cancel_write_to_event": "Rezervasiya ləğv edildikdə, tədbiri silmək əvəzinə tədbir qeydinə yazın",
|
||||
"salesforce_on_every_cancellation": "Hər ləğv zamanı",
|
||||
"report_issue": "Problemi bildirin",
|
||||
"report_issue_description": "GitHub-da bilet təqdim edə və ya tərtibatçı konfransları ilə real vaxt dəstəyi almaq üçün planınızı yüksəldə bilərsiniz",
|
||||
"open_issue": "Problemi açın",
|
||||
"this_is_your_current_plan": "Bu sizin cari planınızdır",
|
||||
"schedule_a_time": "Vaxt təyin edin",
|
||||
"this_includes": "Buna daxildir:",
|
||||
"oauth_client_updated_successfully": "OAuth müştərisi uğurla yeniləndi",
|
||||
"oauth_client_not_found": "OAuth müştərisi tapılmadı.",
|
||||
"subscribe_to_platform": "Platformaya abunə olun",
|
||||
"error_accessing_webhooks": "Vebhuklara giriş zamanı xəta baş verdi.",
|
||||
"webhook_update_failed": "Vebhuku yeniləmək mümkün olmadı.",
|
||||
"webhook_create_failed": "Vebhuk yaratmaq mümkün olmadı.",
|
||||
"invalid_link": "Yanlış link",
|
||||
"currently_subscribed_to_plan": "Hal-hazırda {{planFirstLetter}}{{planRest}} planına abunəsiniz",
|
||||
"user_team": "İstifadəçi/Komanda",
|
||||
"client_id_copied": "Müştəri ID-si kopyalandı!",
|
||||
"client_secret_copied": "Müştəri sirri kopyalandı!",
|
||||
"maintenance_message": "Cal.com komandası planlaşdırılmış texniki xidmət işləri aparır. Hər hansı sualınız varsa, dəstəklə əlaqə saxlayın.",
|
||||
"your_payment_failed": "Ödənişiniz uğursuz oldu",
|
||||
"check_your_inbox": "Gələnlər qutunuzu yoxlayın",
|
||||
"account_created_premium_not_reserved": "Hesabınız yaradıldı, lakin premium adınız rezerv edilmədi.",
|
||||
"email_sent_with_activation_link": "{{email}} ünvanına hesabınızı aktivləşdirmək üçün link göndərdik.",
|
||||
"activate_account_to_purchase_username": "Hesabınızı aktivləşdirdikdən sonra premium istifadəçi adınızı yenidən almağa cəhd edə və ya fərqli bir ad seçə bilərsiniz.",
|
||||
"open_in_gmail": "Gmail-də açın",
|
||||
"dont_see_email": "E-poçt görmürsünüz?",
|
||||
"resend_in_seconds": "{{seconds}} saniyə sonra yenidən göndər",
|
||||
"resend": "Yenidən göndər",
|
||||
"verification_email_sent": "Doğrulama e-poçtu göndərildi",
|
||||
"select_all_members": "Bütün üzvləri seçin",
|
||||
"select_all_members_tooltip": "Bütün üzvləri seçmək, gələcəkdə komandaya əlavə edilən bütün üzvləri də əlavə edəcək.",
|
||||
"form_settings": "Form Parametrləri",
|
||||
"remove_whitelist_status": "Ağ siyahı statusunu silin",
|
||||
"whitelist_user_workflows": "İstifadəçi iş axınlarını ağ siyahıya əlavə edin",
|
||||
"user_workflows_whitelisted": "İstifadəçi iş axınları ağ siyahıya əlavə edildi",
|
||||
"user_workflows_unwhitelisted": "İstifadəçi iş axınları ağ siyahıdan çıxarıldı",
|
||||
"date_and_time": "Tarix & Saat",
|
||||
"email_reminder_upcoming_event_notice": "Bu, qarşıdan gələn tədbiriniz haqqında xatırlatmadır.",
|
||||
"email_reminder_triggered_by_workflow": "Bu xatırladıcı Calda iş axını ilə işə salınıb.",
|
||||
"event_upper_case": "Hadisə",
|
||||
"scheduling_by": "Təqvimləşdirmə edən",
|
||||
"experience_review_prompt": "Son təcrübəniz necə oldu?",
|
||||
"improve_customer_experience_message": "Həmişə müştəri təcrübəsini yaxşılaşdırmağa çalışırıq.",
|
||||
"meeting_satisfaction_question": "Son görüşünüzdən nə qədər məmnun qaldınız?",
|
||||
"meeting_not_joined_question": "görüşə qoşulmadınız?",
|
||||
"reschedule_cta_short": "Buradan yenidən təyin edin.",
|
||||
"hide_organizer_email": "Təşkilatçının e-poçtunu gizlədin",
|
||||
"platform_customer_cant_create_organization": "Siz artıq bir platforma təşkilatının üzvü olduğunuz üçün yeni təşkilat yarada bilməzsiniz. Hər istifadəçi yalnız bir təşkilata aid ola bilər. Zəhmət olmasa, fərqli bir e-poçt ilə yeni bir cal.com hesabı yaradın və həmin hesabdan təşkilat planına abunə olun.",
|
||||
"organization_customer_cant_create_platform": "Siz artıq bir təşkilatın üzvü olduğunuz üçün platforma təşkilatı yarada bilməzsiniz. Hər istifadəçi yalnız bir təşkilata aid ola bilər. Zəhmət olmasa, fərqli bir e-poçt ilə yeni bir cal.com hesabı yaradın və həmin hesabdan platforma planına abunə olun.",
|
||||
"hide_organizer_email_description": "Təşkilatçının e-poçt ünvanını rezervasiya ekranından, e-poçt bildirişlərindən və təqvim tədbirlərindən gizlədin",
|
||||
"you_and_conjunction": "Siz &",
|
||||
"email_survey_triggered_by_workflow": "Bu sorğu Cal-da Workflow tərəfindən başladıldı."
|
||||
"select_verified_email": "Təsdiqlənmiş e-poçt seçin",
|
||||
"custom_reply_to_email_title": "Xüsusi 'Cavab-Ünvanı' e-poçtu",
|
||||
"custom_reply_to_email_description": "Təsdiq e-poçtları üçün təşkilatçının e-poçtu əvəzinə fərqli bir e-poçt ünvanını cavab ünvanı kimi istifadə edin",
|
||||
"email_survey_triggered_by_workflow": "Bu sorğu Cal-da Workflow tərəfindən başladıldı.",
|
||||
"skip_trial": "Sınaq müddətini keçin",
|
||||
"team_trials_skipped_successfully": "Komanda sınaqları uğurla keçildi",
|
||||
"sms_workflow_consent": "Telefon nömrənizi daxil etməklə bu tədbir üçün SMS mesajları almağa razılıq verirsiniz. SMS tarifləri tətbiq oluna bilər.",
|
||||
"routing_preview_more_info_found_insights": "Daha çox məlumatı <0>Marşrutlama Təhlilləri</0> bölməsində tapa bilərsiniz",
|
||||
"results": "Nəticələr",
|
||||
"view_form": "Formaya baxın",
|
||||
"sms_opt_out_message": "SMS mesajlarından imtina etmək üçün STOP yazın",
|
||||
"routing_form_next_in_queue": "Növbədə {{count}} növbəti",
|
||||
"routing_form_select_members_to_email": "E-poçt cavablarını göndərmək üçün üzvləri seçin",
|
||||
"routing_incomplete_booking_tab": "Tamamlanmamış rezervasiyalar",
|
||||
"include_no_show_in_rr_calculation": "Round robin hesablamalarında gəlməyən rezervasiyaları daxil edin",
|
||||
"matching": "Uyğunlaşdırma",
|
||||
"event_redirect": "Tədbir yönləndirməsi",
|
||||
"reset_form": "Formanı sıfırlayın",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Yeni sətirləri bura əlavə edin ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Вашето пълно име",
|
||||
"no_name": "Без име",
|
||||
"enter_number_between_range": "Моля, въведете число между 1 и {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Бързо и лесно - не се изисква акаунт. Идеално за еднократни срещи.",
|
||||
"email_address": "Имейл адрес",
|
||||
"enter_valid_email": "Моля, въведете валиден имейл",
|
||||
"please_schedule_future_call": "Моля, планирайте бъдеща среща, ако не сме свободни в следващите {{seconds}} секунди",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "На място (адрес на участника)",
|
||||
"somewhere_else": "Друго място",
|
||||
"custom_attendee_location": "Персонализирана локация на участника",
|
||||
"continue_as_guest": "Продължи като гост",
|
||||
"any_location": "Всяка локация",
|
||||
"yes": "Да",
|
||||
"no": "Не",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Екипът е обновен успешно",
|
||||
"your_team_updated_successfully": "Вашият екип беше обновен успешно.",
|
||||
"your_org_updated_successfully": "Вашата организация беше обновена успешно.",
|
||||
"error_copying_to_clipboard": "Грешка при копиране в клипборда",
|
||||
"about": "За нас",
|
||||
"team_description": "Няколко изречения за вашия екип. Това ще се показва на URL страницата на екипа ви.",
|
||||
"organization_id": "Идентификатор на организацията",
|
||||
"organization_id_copied": "Идентификаторът на организацията е копиран.",
|
||||
"org_description": "Няколко изречения за вашата организация. Това ще се показва на URL страницата на организацията ви.",
|
||||
"team_id": "Идентификатор на екипа",
|
||||
"team_id_copied": "Идентификаторът на екипа е копиран.",
|
||||
"members": "Членове",
|
||||
"organization_members": "Членове на организацията",
|
||||
"member": "Член",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Сигурни ли сте, че искате да премахнете този член от екипа?",
|
||||
"confirm_disband_team": "Да, разформировай екипа",
|
||||
"confirm_remove_member": "Да, премахни члена",
|
||||
"confirm_subscription_cancellation": "Да, отказвам абонамента",
|
||||
"cancel_subscription": "Отказване на абонамент",
|
||||
"cancel_subscription_description": "Отказването на абонамента ви ще деактивира окончателно текущия ви план. Това действие не може да бъде отменено.",
|
||||
"remove_member": "Премахни член",
|
||||
"manage_your_team": "Управление на вашия екип",
|
||||
"no_teams": "Все още нямате екипи.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL адрес на вашата страница за резервации",
|
||||
"booking_cancel_redirect_uri": "URL адрес на страницата, където потребителите могат да отменят резервацията си",
|
||||
"booking_reschedule_redirect_uri": "URL адрес на страницата, където потребителите могат да пренасрочат резервацията си",
|
||||
"booking_conflict_error": "Този слот вече не е наличен. Моля, върнете се на предишната страница и изберете друго време.",
|
||||
"open_invitations": "Отворени покани",
|
||||
"new_team": "Нов екип",
|
||||
"create_first_team_and_invite_others": "Създайте първия си екип и поканете други потребители за съвместна работа.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Акаунтът ви е създаден с помощта на доставчик на идентичност.",
|
||||
"account_managed_by_identity_provider": "Акаунтът ви се управлява от {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "За да промените имейла си, паролата, да активирате двуфакторна автентикация и други, моля, посетете настройките на вашия {{provider}} акаунт.",
|
||||
"account_managed_by_identity_provider_error": "Вашият акаунт се управлява от друг доставчик на идентичност. Опитайте да влезете с {{provider}}.",
|
||||
"user_creation_error": "Грешка при създаване на нов потребител. Моля, опитайте отново.",
|
||||
"signin_with_google": "Вход с Google",
|
||||
"signin_with_saml": "Вход със SAML",
|
||||
"signin_with_saml_oidc": "Вход със SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Готово сте!",
|
||||
"install_zapier_app": "Моля, първо инсталирайте Zapier приложението от магазина за приложения.",
|
||||
"install_make_app": "Моля, първо инсталирайте Make приложението от магазина за приложения.",
|
||||
"app_installation": "Инсталиране на приложение",
|
||||
"app_not_installed": "Приложението не е инсталирано",
|
||||
"visit_our_app_store": "Съжаляваме, това приложение не е инсталирано на вашия акаунт. Моля, посетете нашия магазин за приложения, за да разгледате това и други страхотни приложения.",
|
||||
"connect_apple_server": "Свързване с Apple сървър",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "когато събитието е отменено",
|
||||
"after_hosts_cal_video_no_show": "След като домакините не се присъединиха към Cal видеото",
|
||||
"after_guests_cal_video_no_show": "След като гостите не се присъединиха към Cal видеото",
|
||||
"join_video_call": "Присъединете се към видео разговора",
|
||||
"sign_in_to_cal_com": "Влезте във вашия Cal.com акаунт",
|
||||
"log_in_to_cal_com": "Влезте в Cal.com",
|
||||
"track_your_meetings": "Проследявайте срещите си, получавайте известия и управлявайте графика си по-ефективно.",
|
||||
"choose_how_you_d_like_to_join_call": "Изберете как искате да се присъедините към този разговор",
|
||||
"new_event_trigger": "когато е резервирано ново събитие",
|
||||
"email_host_action": "изпращане на имейл до домакина",
|
||||
"email_attendee_action": "изпращане на имейл до участниците",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "По избор",
|
||||
"reminder": "Напомняне",
|
||||
"rescheduled": "Пренасрочено",
|
||||
"rescheduled_by": "Пренасрочено от",
|
||||
"original_booking": "Първоначална резервация",
|
||||
"completed": "Завършено",
|
||||
"rating": "Оценка",
|
||||
"reminder_email": "Напомняне: {{eventType}} с {{name}} на {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "Работният процес {{workflowName}} е {{offOn}} успешно",
|
||||
"download_responses": "Изтегли отговорите",
|
||||
"download_responses_description": "Изтегли всички отговори от формуляра в CSV формат.",
|
||||
"view_responses": "Преглед на отговорите",
|
||||
"download": "Изтегли",
|
||||
"downloading": "Изтегляне",
|
||||
"download_recording": "Изтегли записа",
|
||||
"transcription_enabled": "Транскрипциите са активирани",
|
||||
"transcription_stopped": "Транскрипциите са спрени",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Добавяне на нов формуляр към вашия екип",
|
||||
"create_your_first_route": "Създайте първия си маршрут",
|
||||
"route_to_the_right_person": "Насочване към правилния човек според отговорите във формуляра",
|
||||
"form": "Формуляр",
|
||||
"form_description": "Създайте формуляр за маршрутизиране на резервации",
|
||||
"copy_link_to_form": "Копиране на линк към формуляра",
|
||||
"theme": "Тема на страницата за резервации",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Грешен код за потвърждение",
|
||||
"not_verified": "Все още не е потвърдено",
|
||||
"no_availability_in_month": "Няма свободно време през {{month}}",
|
||||
"no_availability_rolling": "Планирането е възможно само до {{days}} дни напред. Моля, проверете отново скоро.",
|
||||
"no_availability_range": "Планирането приключи на {{date}}. Моля, проверете отново скоро.",
|
||||
"view_previous_month": "Преглед на предишния месец",
|
||||
"view_next_month": "Преглед на следващия месец",
|
||||
"send_code": "Изпращане на код",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Плащането за това събитие вече не е възможно",
|
||||
"booking_with_payment_cancelled_already_paid": "Възстановяването на сумата за тази резервация е в процес на обработка.",
|
||||
"booking_with_payment_cancelled_refunded": "Плащането за тази резервация е възстановено.",
|
||||
"booking_with_payment_cancelled_no_refund": "Съгласно политиката за възстановяване на средства за събитието, плащането за резервацията не подлежи на възстановяване.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Периодът за възстановяване на средства за събитието е изтекъл. Следователно плащането за резервацията не подлежи на възстановяване.",
|
||||
"booking_confirmation_failed": "Потвърждението на резервацията е неуспешно",
|
||||
"not_enough_seats": "Няма достатъчно места",
|
||||
"form_builder_field_already_exists": "Поле с това име вече съществува",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Open users availability",
|
||||
"organization_no_slots_notification_switch_title": "Получавайте известия, когато вашият екип няма свободна заетост",
|
||||
"organization_no_slots_notification_switch_description": "Администраторите ще получават имейл известия, когато потребител се опита да резервира член на екипа и се сблъска с 'Няма свободна заетост'. Изпращаме този имейл след две появявания и ви напомняме на всеки 7 дни за потребител.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Деактивиране на SMS известия за типове събития само с телефон",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Деактивиране на автоматичните SMS известия за типове събития, които изискват само телефонен номер (attendeePhoneNumber) като задължителен въпрос, с имейл като незадължителен или не изискван",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} ви добави към организацията {{team}} в {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} ви покани да се присъедините към организацията {{team}} в {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} ви добави към екипа {{team}} от организацията {{parentTeamName}} в {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Вашата връзка беше променена от {{a0}} на {{a1}}, но не се притеснявайте, всички предишни връзки все още работят и пренасочват правилно. <br /><br />Моля, имайте предвид: Всички ваши лични типове събития са преместени в организацията <strong>{{teamName}}</strong>, което може да включва и потенциална лична връзка.<br /><br />Моля, влезте и се уверете, че нямате лични събития в новия си организационен акаунт.<br /><br />За лични събития препоръчваме да създадете нов акаунт с личен имейл адрес.<br /><br />Насладете се на новата си чиста връзка: {{a2}}",
|
||||
"email_organization_created|subject": "Вашата организация е създадена",
|
||||
"your_current_plan": "Вашият текущ план",
|
||||
"organization_price_per_user_month": "$37 на потребител на месец (минимум 30 места)",
|
||||
"organization_price_per_user_month": "$37 на потребител на месец",
|
||||
"privacy_organization_description": "Управлявайте настройките за поверителност на вашата организация",
|
||||
"privacy": "Поверителност",
|
||||
"team_will_be_under_org": "Новите екипи ще бъдат под вашата организация",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "С продължаването си, вие се съгласявате с нашите",
|
||||
"terms": "Условия",
|
||||
"always_show_x_days": "Винаги показвай {{x}} свободни дни",
|
||||
"team_subscription_cancelled_successfully": "Абонаментът на екипа е отменен успешно",
|
||||
"team_subscription_cancellation_error": "Грешка при отмяна на абонамента на екипа",
|
||||
"unable_to_subscribe_to_the_platform": "Възникна грешка при опит за абониране за плана на платформата, моля опитайте отново по-късно",
|
||||
"updating_oauth_client_error": "Възникна грешка при актуализиране на OAuth клиента, моля опитайте отново по-късно",
|
||||
"creating_oauth_client_error": "Възникна грешка при създаване на OAuth клиента, моля опитайте отново по-късно",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Пропусни създаването на запис {{entry}}, ако не съществува в Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Ако контактът не съществува под акаунт, създай нов лийд от участника",
|
||||
"salesforce_create_new_contact_under_account": "Създай нов контакт под акаунт базиран на имейл домейна на участника и съществуващите контакти",
|
||||
"salesforce_change_record_owner_on_booking": "Промяна на собственика на записа при резервация",
|
||||
"mass_assign_attributes": "Масово задаване на атрибути",
|
||||
"reroute_preview_custom_message": "Това води до показване на персонализирано съобщение. Опитайте да промените отговора, за да пренасочите към събитие",
|
||||
"reroute_preview_external_redirect": "Това води до пренасочване към {{externalUrl}}. Опитайте да промените отговора, за да пренасочите към събитие",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Пренасочени към за период",
|
||||
"per_day": "За ден",
|
||||
"per_week": "За седмица",
|
||||
"per_month": "За месец",
|
||||
"per_month": "на месец",
|
||||
"routing_form_insights_assignment_reason": "Причина за назначаване",
|
||||
"access_denied": "Достъпът е отказан",
|
||||
"salesforce_route_to_owner": "Собственикът на контакта ще бъде Round Robin домакин, ако е наличен",
|
||||
"salesforce_add_attendees_as": "Добавяне на нови участници като",
|
||||
"salesforce_do_not_route_to_owner": "Собственикът на контакта няма да бъде принудително избран (все пак може да бъде домакин, ако отговаря на атрибутите и критериите за Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Пренасочване към потребител, който съответства на поле за търсене в акаунта",
|
||||
"salesforce_option": "Salesforce опция",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Недостиг",
|
||||
"routing_form": "Форма за маршрутизиране",
|
||||
"go_back_and_save": "Върни се и запази",
|
||||
"save_changes": "Запази промените",
|
||||
"leave_without_saving": "Излез без да запазиш",
|
||||
"leave_without_saving_description": "Сигурни ли сте, че искате да излезете без да запазите промените във вашата форма за маршрутизиране?",
|
||||
"something_unexpected_occurred": "Възникна неочаквана грешка",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Упълномощаване",
|
||||
"next": "Напред",
|
||||
"hide": "Скрий",
|
||||
"show": "Покажи",
|
||||
"utm_params": "UTM параметри",
|
||||
"no_utm_params": "Няма налични UTM параметри.",
|
||||
"asc": "Възх",
|
||||
"desc": "Низх",
|
||||
"verify_email_change": "Потвърди промяната на имейл",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Трябва да имате минимален брой публикувани екипи",
|
||||
"you_are_part_of_this_organization_already": "Вече сте част от тази организация",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Вие сте част от друга организация, не можете да създадете нова организация",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Вие сте част от друга платформена организация, не можете да създадете нова организация",
|
||||
"organization_payment_success": "Успешно плащане за организацията",
|
||||
"organization_payment_success_description": "Вашата организация е създадена успешно",
|
||||
"this_may_take_a_few_seconds": "Това може да отнеме няколко секунди...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Въвеждането в организацията вече е завършено",
|
||||
"organization_onboarding_already_exists": "Въвеждането в организацията вече съществува",
|
||||
"organization_onboarding_not_found": "Въвеждането в организацията не е намерено",
|
||||
"payment_successful": "Успешно плащане",
|
||||
"payment_successful": "Плащането е успешно!",
|
||||
"handover_onboarding_page_title": "Предаване на въвеждането",
|
||||
"handover_onboarding_page_description": "Предаване на въвеждането на потребителя",
|
||||
"organization_already_exists_with_this_slug": "Вече съществува организация с този слъг",
|
||||
@@ -3022,6 +3061,9 @@
|
||||
"tip_username_plus": "Съвет: Можете да добавите '+' между потребителските имена: cal.com/anna+brian, за да създадете динамична групова среща",
|
||||
"user_has_no_team_yet": "Все още нямате екип",
|
||||
"no_team_members": "Все още нямате членове на екипа",
|
||||
"recurring_event_doesnt_support_seats": "Повтарящото се събитие не поддържа функцията за места. Направете го неповтарящо се, за да активирате места.",
|
||||
"seats_doesnt_support_recurring": "Функцията за места не поддържа повтарящи се събития. Деактивирайте функцията за места, за да го направите повтарящо се.",
|
||||
"recurring_event_seats_error": "Повтарящото се събитие не поддържа функцията за места. Деактивирайте функцията за места или направете събитието неповтарящо се.",
|
||||
"segment": "Сегмент",
|
||||
"rename": "Преименуване",
|
||||
"rename_segment": "Преименуване на сегмент",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Най-много отменени резервации",
|
||||
"name_or_email": "Име или имейл",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Ако не е намерен контакт, връщане към собственика на лийда, ако съществува",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавете новите си низове над този ред ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Дата и час",
|
||||
"email_reminder_upcoming_event_notice" : "Това е напомняне за предстоящото ви събитие.",
|
||||
"email_reminder_triggered_by_workflow" : "Това напомняне е задействано от работен процес в Cal.",
|
||||
"enable_delegation_credential": "Активиране на делегирани идентификационни данни",
|
||||
"enable_delegation_credential_description": "Предоставете на Cal.com автоматичен достъп до календарите на всички членове на организацията чрез активиране на делегирани идентификационни данни.",
|
||||
"disable_delegation_credential": "Деактивиране на делегирани идентификационни данни",
|
||||
"disable_delegation_credential_description": "След деактивиране на делегираните идентификационни данни, членовете на организацията, които не са свързали календарите си, ще трябва да го направят ръчно.",
|
||||
"last_active": "Последна активност",
|
||||
"member_since": "Член от",
|
||||
"last_updated": "Последно обновено",
|
||||
"salesforce_on_cancel_write_to_event": "При отменена резервация, запиши в записа на събитието вместо да изтриеш събитието",
|
||||
"salesforce_on_every_cancellation": "При всяка отмяна",
|
||||
"report_issue": "Докладвай проблем",
|
||||
"report_issue_description": "Можете да подадете билет в GitHub или да надградите плана си, за да получите поддръжка в реално време с конференции за разработчици",
|
||||
"open_issue": "Отвори проблем",
|
||||
"this_is_your_current_plan": "Това е текущият ви план",
|
||||
"schedule_a_time": "Планирайте време",
|
||||
"this_includes": "Това включва:",
|
||||
"oauth_client_updated_successfully": "OAuth клиентът е актуализиран успешно",
|
||||
"oauth_client_not_found": "OAuth клиентът не е намерен.",
|
||||
"subscribe_to_platform": "Абонирайте се за платформата",
|
||||
"error_accessing_webhooks": "Грешка при опит за достъп до уебхуки.",
|
||||
"webhook_update_failed": "Неуспешно актуализиране на уебхук.",
|
||||
"webhook_create_failed": "Неуспешно създаване на уебхук.",
|
||||
"invalid_link": "Невалидна връзка",
|
||||
"currently_subscribed_to_plan": "В момента сте абонирани за плана {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Потребител/Екип",
|
||||
"client_id_copied": "Идентификаторът на клиента е копиран!",
|
||||
"client_secret_copied": "Клиентската тайна е копирана!",
|
||||
"maintenance_message": "Екипът на Cal.com извършва планирана поддръжка. Ако имате въпроси, моля, свържете се с поддръжката.",
|
||||
"your_payment_failed": "Плащането ви не бе успешно",
|
||||
"check_your_inbox": "Проверете входящата си поща",
|
||||
"account_created_premium_not_reserved": "Вашият акаунт е създаден, но премиум потребителското име не е запазено.",
|
||||
"email_sent_with_activation_link": "Изпратихме имейл до {{email}} с връзка за активиране на вашия акаунт.",
|
||||
"activate_account_to_purchase_username": "След като активирате акаунта си, ще можете да опитате отново да закупите премиум потребителското си име или да изберете друго.",
|
||||
"open_in_gmail": "Отворете в Gmail",
|
||||
"dont_see_email": "Не виждате имейл?",
|
||||
"resend_in_seconds": "Повторно изпращане след {{seconds}} секунди",
|
||||
"resend": "Изпрати отново",
|
||||
"verification_email_sent": "Имейлът за потвърждение е изпратен",
|
||||
"select_all_members": "Изберете всички членове",
|
||||
"select_all_members_tooltip": "Избирането на всички членове ще добави всички бъдещи членове на екипа, когато бъдат добавени към екипа.",
|
||||
"form_settings": "Настройки на формуляра",
|
||||
"remove_whitelist_status": "Премахване на статус в белия списък",
|
||||
"whitelist_user_workflows": "Добавяне на потребителски работни процеси в белия списък",
|
||||
"user_workflows_whitelisted": "Потребителските работни процеси са добавени в белия списък",
|
||||
"user_workflows_unwhitelisted": "Потребителските работни процеси са премахнати от белия списък",
|
||||
"date_and_time": "Дата и час",
|
||||
"email_reminder_upcoming_event_notice": "Това е напомняне за предстоящото ви събитие.",
|
||||
"email_reminder_triggered_by_workflow": "Това напомняне е задействано от работен процес в Cal.",
|
||||
"event_upper_case": "Събитие",
|
||||
"scheduling_by": "График от",
|
||||
"experience_review_prompt": "Как бе вашето последно преживяване?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Колко сте доволни от последната си среща?",
|
||||
"meeting_not_joined_question": "не присъствахте на срещата?",
|
||||
"reschedule_cta_short": "Пренасрочете тук.",
|
||||
"hide_organizer_email": "Скриване на имейла на организатора",
|
||||
"platform_customer_cant_create_organization": "Вече сте част от платформена организация, поради което не можете да създадете нова организация. Всеки потребител може да принадлежи само към една организация. Моля, създайте нов акаунт в cal.com с различен имейл и използвайте този акаунт, за да се абонирате за плана за организации.",
|
||||
"organization_customer_cant_create_platform": "Вече сте част от организация, поради което не можете да създадете платформена организация. Всеки потребител може да принадлежи само към една организация. Моля, създайте нов акаунт в cal.com с различен имейл и използвайте този акаунт, за да се абонирате за платформения план.",
|
||||
"hide_organizer_email_description": "Скриване на имейл адреса на организатора от екрана за резервации, имейл известията и календарните събития",
|
||||
"you_and_conjunction": "Вие &",
|
||||
"email_survey_triggered_by_workflow": "Тази анкета беше стартирана от Workflow в Cal."
|
||||
"select_verified_email": "Изберете потвърден имейл",
|
||||
"custom_reply_to_email_title": "Персонализиран имейл за отговор",
|
||||
"custom_reply_to_email_description": "Използвайте различен имейл адрес като адрес за отговор в имейлите за потвърждение вместо имейла на организатора",
|
||||
"email_survey_triggered_by_workflow": "Тази анкета беше стартирана от Workflow в Cal.",
|
||||
"skip_trial": "Пропускане на пробния период",
|
||||
"team_trials_skipped_successfully": "Пробните периоди на екипа са пропуснати успешно",
|
||||
"sms_workflow_consent": "С въвеждането на вашия телефонен номер давате съгласие да получавате SMS съобщения за това събитие. Може да се начислят такси за SMS.",
|
||||
"routing_preview_more_info_found_insights": "Повече информация може да бъде намерена в <0>Анализи на маршрутизацията</0>",
|
||||
"results": "Резултати",
|
||||
"view_form": "Преглед на формуляра",
|
||||
"sms_opt_out_message": "Изпратете STOP, за да се отпишете от SMS съобщенията",
|
||||
"routing_form_next_in_queue": "{{count}} следващи на опашката",
|
||||
"routing_form_select_members_to_email": "Изпращане на имейл отговори до",
|
||||
"routing_incomplete_booking_tab": "Незавършени резервации",
|
||||
"include_no_show_in_rr_calculation": "Включване на неявилите се резервации в изчисленията на round robin",
|
||||
"matching": "Съвпадение",
|
||||
"event_redirect": "Пренасочване на събитие",
|
||||
"reset_form": "Нулиране на формуляра",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавете новите си низове над този ред ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "El teu nom complet",
|
||||
"no_name": "Sense nom",
|
||||
"enter_number_between_range": "Si us plau, introdueix un número entre 1 i {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Ràpid i fàcil - no cal compte. Perfecte per a reunions puntuals.",
|
||||
"email_address": "Adreça de correu electrònic",
|
||||
"enter_valid_email": "Si us plau, introdueix un correu electrònic vàlid",
|
||||
"please_schedule_future_call": "Si us plau, programa una trucada futura si no estem disponibles en {{seconds}} segons",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Presencial (adreça de l'assistent)",
|
||||
"somewhere_else": "Un altre lloc",
|
||||
"custom_attendee_location": "Ubicació personalitzada de l'assistent",
|
||||
"continue_as_guest": "Continua com a convidat",
|
||||
"any_location": "Qualsevol ubicació",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Equip actualitzat correctament",
|
||||
"your_team_updated_successfully": "El teu equip s'ha actualitzat correctament.",
|
||||
"your_org_updated_successfully": "La teva organització s'ha actualitzat correctament.",
|
||||
"error_copying_to_clipboard": "Error en copiar al porta-retalls",
|
||||
"about": "Sobre",
|
||||
"team_description": "Unes quantes frases sobre el teu equip. Això apareixerà a la pàgina URL del teu equip.",
|
||||
"organization_id": "ID de l'organització",
|
||||
"organization_id_copied": "ID de l'organització copiat.",
|
||||
"org_description": "Unes quantes frases sobre la teva organització. Això apareixerà a la pàgina URL de la teva organització.",
|
||||
"team_id": "ID de l'equip",
|
||||
"team_id_copied": "ID de l'equip copiat.",
|
||||
"members": "Membres",
|
||||
"organization_members": "Membres de l'organització",
|
||||
"member": "Membre",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Estàs segur que vols eliminar aquest membre de l'equip?",
|
||||
"confirm_disband_team": "Sí, dissoldre l'equip",
|
||||
"confirm_remove_member": "Sí, eliminar membre",
|
||||
"confirm_subscription_cancellation": "Sí, cancel·la la subscripció",
|
||||
"cancel_subscription": "Cancel·la la subscripció",
|
||||
"cancel_subscription_description": "Cancel·lar la teva subscripció desactivarà permanentment el teu pla actual. Aquesta acció no es pot desfer.",
|
||||
"remove_member": "Eliminar membre",
|
||||
"manage_your_team": "Gestiona el teu equip",
|
||||
"no_teams": "Encara no tens cap equip.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL de la teva pàgina de reserves",
|
||||
"booking_cancel_redirect_uri": "URL de la pàgina on els teus usuaris poden cancel·lar la seva reserva",
|
||||
"booking_reschedule_redirect_uri": "URL de la pàgina on els teus usuaris poden reprogramar la seva reserva",
|
||||
"booking_conflict_error": "Aquest horari ja no està disponible. Si us plau, torna a la pàgina anterior i selecciona un altre moment.",
|
||||
"open_invitations": "Invitacions obertes",
|
||||
"new_team": "Nou equip",
|
||||
"create_first_team_and_invite_others": "Crea el teu primer equip i convida altres usuaris a treballar junts.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "El teu compte s'ha creat utilitzant un proveïdor d'identitat",
|
||||
"account_managed_by_identity_provider": "El teu compte està gestionat per {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Per canviar el teu correu electrònic, contrasenya, activar l'autenticació de dos factors i més, visita la configuració del teu compte de {{provider}}",
|
||||
"account_managed_by_identity_provider_error": "El teu compte està gestionat per un proveïdor d'identitat diferent. Prova d'iniciar sessió amb {{provider}}.",
|
||||
"user_creation_error": "Error en crear un nou usuari. Si us plau, torna-ho a provar.",
|
||||
"signin_with_google": "Inicia sessió amb Google",
|
||||
"signin_with_saml": "Inicia sessió amb SAML",
|
||||
"signin_with_saml_oidc": "Inicia sessió amb SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Ja està tot llest!",
|
||||
"install_zapier_app": "Si us plau, primer instal·la l'aplicació de Zapier a la botiga d'aplicacions",
|
||||
"install_make_app": "Si us plau, primer instal·la l'aplicació de Make a la botiga d'aplicacions",
|
||||
"app_installation": "Instal·lació de l'aplicació",
|
||||
"app_not_installed": "Aplicació no instal·lada",
|
||||
"visit_our_app_store": "Ho sentim, aquesta aplicació no està instal·lada al teu compte. Visita la nostra botiga d'aplicacions per explorar i descobrir aquesta i altres aplicacions genials",
|
||||
"connect_apple_server": "Connecta amb el servidor d'Apple",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "quan es cancel·la l'esdeveniment",
|
||||
"after_hosts_cal_video_no_show": "Després que els amfitrions no s'hagin unit al vídeo de Cal",
|
||||
"after_guests_cal_video_no_show": "Després que els convidats no s'hagin unit al vídeo de Cal",
|
||||
"join_video_call": "Uneix-te a la videotrucada",
|
||||
"sign_in_to_cal_com": "Inicia sessió al teu compte de Cal.com",
|
||||
"log_in_to_cal_com": "Inicia sessió a Cal.com",
|
||||
"track_your_meetings": "Fes seguiment de les teves reunions, rep notificacions i gestiona la teva agenda de manera més efectiva.",
|
||||
"choose_how_you_d_like_to_join_call": "Tria com vols unir-te a aquesta trucada",
|
||||
"new_event_trigger": "quan es reserva un nou esdeveniment",
|
||||
"email_host_action": "enviar correu a l'amfitrió",
|
||||
"email_attendee_action": "enviar correu als assistents",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Personalitzat",
|
||||
"reminder": "Recordatori",
|
||||
"rescheduled": "Reprogramat",
|
||||
"rescheduled_by": "Reprogramat per",
|
||||
"original_booking": "Reserva original",
|
||||
"completed": "Completat",
|
||||
"rating": "Valoració",
|
||||
"reminder_email": "Recordatori: {{eventType}} amb {{name}} el {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "El flux de treball {{workflowName}} s'ha {{offOn}} correctament",
|
||||
"download_responses": "Descarrega les respostes",
|
||||
"download_responses_description": "Descarrega totes les respostes del teu formulari en format CSV",
|
||||
"view_responses": "Veure respostes",
|
||||
"download": "Descarrega",
|
||||
"downloading": "Descarregant",
|
||||
"download_recording": "Descarrega l'enregistrament",
|
||||
"transcription_enabled": "Les transcripcions estan activades ara",
|
||||
"transcription_stopped": "Les transcripcions s'han aturat ara",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Afegeix un nou formulari al teu equip",
|
||||
"create_your_first_route": "Crea la teva primera ruta",
|
||||
"route_to_the_right_person": "Dirigeix a la persona adequada segons les respostes del formulari",
|
||||
"form": "Formulari",
|
||||
"form_description": "Crea el teu formulari per encaminar una reserva",
|
||||
"copy_link_to_form": "Copia l'enllaç al formulari",
|
||||
"theme": "Tema de la pàgina de reserves",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Codi de verificació incorrecte",
|
||||
"not_verified": "Encara no verificat",
|
||||
"no_availability_in_month": "No hi ha disponibilitat al {{month}}",
|
||||
"no_availability_rolling": "La programació només està disponible fins a {{days}} dies per endavant. Si us plau, torna a comprovar-ho aviat.",
|
||||
"no_availability_range": "La programació va finalitzar el {{date}}. Si us plau, torneu a comprovar-ho aviat.",
|
||||
"view_previous_month": "Veure el mes anterior",
|
||||
"view_next_month": "Veure el mes següent",
|
||||
"send_code": "Enviar codi",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Ja no és possible pagar per aquest esdeveniment",
|
||||
"booking_with_payment_cancelled_already_paid": "El reemborsament d'aquest pagament de reserva està en camí.",
|
||||
"booking_with_payment_cancelled_refunded": "S'ha reemborsat el pagament d'aquesta reserva.",
|
||||
"booking_with_payment_cancelled_no_refund": "Segons la política de reemborsament de l'esdeveniment, el pagament de la reserva no és reemborsable.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "El període de reemborsament de l'esdeveniment ha caducat. Per tant, el pagament de la reserva no és reemborsable.",
|
||||
"booking_confirmation_failed": "La confirmació de la reserva ha fallat",
|
||||
"not_enough_seats": "No hi ha prou places",
|
||||
"form_builder_field_already_exists": "Ja existeix un camp amb aquest nom",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Obre la disponibilitat dels usuaris",
|
||||
"organization_no_slots_notification_switch_title": "Rep notificacions quan el teu equip no tingui disponibilitat",
|
||||
"organization_no_slots_notification_switch_description": "Els administradors rebran notificacions per correu electrònic quan un usuari intenti reservar amb un membre de l'equip i es trobi amb 'Sense disponibilitat'. Activem aquest correu després de dues ocurrències i t'ho recordem cada 7 dies per usuari.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Desactivar les notificacions SMS per a tipus d'esdeveniments només amb telèfon",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Desactivar les notificacions SMS automatitzades per a tipus d'esdeveniments que només tenen el número de telèfon (attendeePhoneNumber) com a pregunta obligatòria amb el correu electrònic com a opcional o no requerit",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} t'ha afegit a l'organització {{team}} a {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} t'ha convidat a unir-te a l'organització {{team}} a {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} t'ha afegit a l'equip {{team}} de l'organització {{parentTeamName}} a {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "El teu enllaç ha canviat de {{a0}} a {{a1}}, però no et preocupis, tots els enllaços anteriors segueixen funcionant i redirigint adequadament. <br /><br />Tingues en compte: Tots els teus tipus d'esdeveniments personals s'han mogut a l'organització <strong>{{teamName}}</strong>, que també pot incloure un possible enllaç personal.<br /><br />Si us plau, inicia sessió i assegura't que no tens esdeveniments privats al teu nou compte d'organització.<br /><br />Per a esdeveniments personals, recomanem crear un nou compte amb una adreça de correu electrònic personal.<br /><br />Gaudeix del teu nou enllaç net: {{a2}}",
|
||||
"email_organization_created|subject": "S'ha creat la teva organització",
|
||||
"your_current_plan": "El teu pla actual",
|
||||
"organization_price_per_user_month": "37$ per usuari al mes (mínim 30 usuaris)",
|
||||
"organization_price_per_user_month": "37$ per usuari al mes",
|
||||
"privacy_organization_description": "Gestiona la configuració de privacitat de la teva organització",
|
||||
"privacy": "Privadesa",
|
||||
"team_will_be_under_org": "Els nous equips estaran sota la vostra organització",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "En continuar, acceptes les nostres",
|
||||
"terms": "Condicions",
|
||||
"always_show_x_days": "Sempre {{x}} dies disponibles",
|
||||
"team_subscription_cancelled_successfully": "Subscripció d'equip cancel·lada amb èxit",
|
||||
"team_subscription_cancellation_error": "Error en cancel·lar la subscripció d'equip",
|
||||
"unable_to_subscribe_to_the_platform": "S'ha produït un error en intentar subscriure's al pla de la plataforma, torna-ho a provar més tard",
|
||||
"updating_oauth_client_error": "S'ha produït un error en actualitzar el client OAuth, torna-ho a provar més tard",
|
||||
"creating_oauth_client_error": "S'ha produït un error en crear el client OAuth, torna-ho a provar més tard",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Omet la creació del registre {{entry}} si no existeix a Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Si el contacte no existeix sota un compte, crea un nou lead de l'assistent",
|
||||
"salesforce_create_new_contact_under_account": "Crea un nou contacte sota un compte basat en el domini de correu de l'assistent i els contactes existents",
|
||||
"salesforce_change_record_owner_on_booking": "Canviar el propietari del registre en la reserva",
|
||||
"mass_assign_attributes": "Assignació massiva d'atributs",
|
||||
"reroute_preview_custom_message": "Això resulta en mostrar un missatge personalitzat. Prova de canviar la resposta per redirigir a un esdeveniment",
|
||||
"reroute_preview_external_redirect": "Això resulta en redirigir a {{externalUrl}}. Prova de canviar la resposta per redirigir a un esdeveniment",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Redirigit a per període",
|
||||
"per_day": "Per dia",
|
||||
"per_week": "Per setmana",
|
||||
"per_month": "Per mes",
|
||||
"per_month": "al mes",
|
||||
"routing_form_insights_assignment_reason": "Motiu d'assignació",
|
||||
"access_denied": "Accés denegat",
|
||||
"salesforce_route_to_owner": "El propietari del contacte serà l'amfitrió del Round Robin si està disponible",
|
||||
"salesforce_add_attendees_as": "Afegir nous assistents com a",
|
||||
"salesforce_do_not_route_to_owner": "El propietari del contacte no serà forçat (pot ser amfitrió si coincideix amb els atributs i criteris del Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Redirigir a un usuari que coincideixi amb un camp de cerca en un compte",
|
||||
"salesforce_option": "Opció de Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Dèficit",
|
||||
"routing_form": "Formulari d'encaminament",
|
||||
"go_back_and_save": "Torna enrere i desa",
|
||||
"save_changes": "Desar canvis",
|
||||
"leave_without_saving": "Surt sense desar",
|
||||
"leave_without_saving_description": "Estàs segur que vols sortir sense desar els canvis al formulari de rutes?",
|
||||
"something_unexpected_occurred": "S'ha produït un error inesperat",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autoritzar",
|
||||
"next": "Següent",
|
||||
"hide": "Amaga",
|
||||
"show": "Mostrar",
|
||||
"utm_params": "Paràmetres UTM",
|
||||
"no_utm_params": "No hi ha paràmetres UTM disponibles.",
|
||||
"asc": "Asc",
|
||||
"desc": "Desc",
|
||||
"verify_email_change": "Verifica el canvi de correu electrònic",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Necessiteu tenir un mínim d'equips publicats",
|
||||
"you_are_part_of_this_organization_already": "Ja formeu part d'aquesta organització",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Formeu part d'una altra organització, no podeu crear-ne una de nova",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Formeu part d'una altra organització de plataforma, no podeu crear-ne una de nova",
|
||||
"organization_payment_success": "Pagament de l'organització realitzat amb èxit",
|
||||
"organization_payment_success_description": "La vostra organització s'ha creat correctament",
|
||||
"this_may_take_a_few_seconds": "Això pot trigar uns segons...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "La incorporació de l'organització ja s'ha completat",
|
||||
"organization_onboarding_already_exists": "La incorporació de l'organització ja existeix",
|
||||
"organization_onboarding_not_found": "No s'ha trobat la incorporació de l'organització",
|
||||
"payment_successful": "Pagament realitzat amb èxit",
|
||||
"payment_successful": "Pagament realitzat amb èxit!",
|
||||
"handover_onboarding_page_title": "Traspàs d'incorporació",
|
||||
"handover_onboarding_page_description": "Traspàs d'incorporació a l'usuari",
|
||||
"organization_already_exists_with_this_slug": "Ja existeix una organització amb aquest slug",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Enllaç",
|
||||
"rows_per_page": "files per pàgina",
|
||||
"pagination_status": "{{currentRange}} de {{totalItems}}",
|
||||
"tip_username_plus": "Consell: Pots afegir un '+' entre noms d'usuari: cal.com/anna+brian per crear una reunió de grup dinàmica",
|
||||
"tip_username_plus": "Consell: Podeu afegir un '+' entre noms d'usuari: cal.com/anna+brian per crear una reunió de grup dinàmica",
|
||||
"user_has_no_team_yet": "Encara no tens cap equip",
|
||||
"no_team_members": "Encara no tens membres a l'equip",
|
||||
"recurring_event_doesnt_support_seats": "Els esdeveniments recurrents no admeten la funció de seients. Feu-lo no recurrent per habilitar els seients.",
|
||||
"seats_doesnt_support_recurring": "La funció de seients no admet esdeveniments recurrents. Desactiveu la funció de seients per fer-lo recurrent.",
|
||||
"recurring_event_seats_error": "Els esdeveniments recurrents no admeten la funció de seients. Desactiveu la funció de seients o feu que l'esdeveniment no sigui recurrent.",
|
||||
"segment": "Segment",
|
||||
"rename": "Canviar el nom",
|
||||
"rename_segment": "Canviar el nom del segment",
|
||||
@@ -3053,7 +3095,50 @@
|
||||
"most_cancelled_bookings": "Reserves més cancel·lades",
|
||||
"name_or_email": "Nom o correu electrònic",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Si no es troba cap contacte, recorre al propietari del lead si existeix",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Afegiu les vostres noves cadenes a dalt ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"enable_delegation_credential": "Activar credencial de delegació",
|
||||
"enable_delegation_credential_description": "Concediu a Cal.com accés automàtic als calendaris de tots els membres de l'organització activant la credencial de delegació.",
|
||||
"disable_delegation_credential": "Desactivar credencial de delegació",
|
||||
"disable_delegation_credential_description": "Un cop desactivada la credencial de delegació, els membres de l'organització que no hagin connectat els seus calendaris hauran de fer-ho manualment.",
|
||||
"last_active": "Última activitat",
|
||||
"member_since": "Membre des de",
|
||||
"last_updated": "Última actualització",
|
||||
"salesforce_on_cancel_write_to_event": "En cancel·lar la reserva, escriu al registre d'esdeveniments en lloc d'eliminar l'esdeveniment",
|
||||
"salesforce_on_every_cancellation": "En cada cancel·lació",
|
||||
"report_issue": "Informar d'un problema",
|
||||
"report_issue_description": "Pots enviar un tiquet a GitHub o actualitzar el teu pla per rebre suport en temps real amb conferències de desenvolupadors",
|
||||
"open_issue": "Obrir incidència",
|
||||
"this_is_your_current_plan": "Aquest és el teu pla actual",
|
||||
"schedule_a_time": "Programa una hora",
|
||||
"this_includes": "Això inclou:",
|
||||
"oauth_client_updated_successfully": "Client OAuth actualitzat correctament",
|
||||
"oauth_client_not_found": "Client OAuth no trobat.",
|
||||
"subscribe_to_platform": "Subscriu-te a la plataforma",
|
||||
"error_accessing_webhooks": "Error en intentar accedir als webhooks.",
|
||||
"webhook_update_failed": "No s'ha pogut actualitzar el webhook.",
|
||||
"webhook_create_failed": "No s'ha pogut crear el webhook.",
|
||||
"invalid_link": "Enllaç no vàlid",
|
||||
"currently_subscribed_to_plan": "Actualment estàs subscrit al pla {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Usuari/Equip",
|
||||
"client_id_copied": "ID de client copiat!",
|
||||
"client_secret_copied": "Secret de client copiat!",
|
||||
"maintenance_message": "L'equip de Cal.com està realitzant un manteniment programat. Si tens alguna pregunta, contacta amb el suport.",
|
||||
"your_payment_failed": "El teu pagament ha fallat",
|
||||
"check_your_inbox": "Comprova la teva safata d'entrada",
|
||||
"account_created_premium_not_reserved": "S'ha creat el teu compte, però el teu premium no s'ha reservat.",
|
||||
"email_sent_with_activation_link": "Hem enviat un correu electrònic a {{email}} amb un enllaç per activar el teu compte.",
|
||||
"activate_account_to_purchase_username": "Un cop activis el teu compte, podràs intentar comprar el teu nom d'usuari premium de nou o seleccionar-ne un de diferent.",
|
||||
"open_in_gmail": "Obre a Gmail",
|
||||
"dont_see_email": "No veus cap correu electrònic?",
|
||||
"resend_in_seconds": "Torna a enviar en {{seconds}} segons",
|
||||
"resend": "Torna a enviar",
|
||||
"verification_email_sent": "Correu de verificació enviat",
|
||||
"select_all_members": "Selecciona tots els membres",
|
||||
"select_all_members_tooltip": "Seleccionar tots els membres afegirà tots els futurs membres de l'equip quan s'afegeixin a l'equip.",
|
||||
"form_settings": "Configuració del formulari",
|
||||
"remove_whitelist_status": "Elimina l'estat de llista blanca",
|
||||
"whitelist_user_workflows": "Afegeix fluxos d'usuari a la llista blanca",
|
||||
"user_workflows_whitelisted": "Fluxos d'usuari afegits a la llista blanca",
|
||||
"user_workflows_unwhitelisted": "Fluxos d'usuari eliminats de la llista blanca",
|
||||
"date_and_time": "Data i hora",
|
||||
"email_reminder_upcoming_event_notice": "Aquest és un recordatori del vostre proper esdeveniment.",
|
||||
"email_reminder_triggered_by_workflow": "Aquest recordatori s'ha activat per un flux de treball a Cal.",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Què satisfet esteu amb la vostra última reunió?",
|
||||
"meeting_not_joined_question": "no vas assistir a la reunió?",
|
||||
"reschedule_cta_short": "Reprograma aquí.",
|
||||
"hide_organizer_email": "Amaga el correu electrònic de l'organitzador",
|
||||
"platform_customer_cant_create_organization": "Ja formes part d'una organització de plataforma, per això no pots crear una nova organització. Cada usuari només pot pertànyer a una organització. Si us plau, crea un nou compte de cal.com amb un correu electrònic diferent i utilitza aquest compte per subscriure't al pla d'organitzacions.",
|
||||
"organization_customer_cant_create_platform": "Ja formes part d'una organització, per això no pots crear una organització de plataforma. Cada usuari només pot pertànyer a una organització. Si us plau, crea un nou compte de cal.com amb un correu electrònic diferent i utilitza aquest compte per subscriure't al pla de plataforma.",
|
||||
"hide_organizer_email_description": "Amaga l'adreça de correu electrònic de l'organitzador de la pantalla de reserva, les notificacions per correu electrònic i els esdeveniments del calendari",
|
||||
"you_and_conjunction": "Vosaltres &",
|
||||
"email_survey_triggered_by_workflow": "Aquesta enquesta va ser activada per un Workflow a Cal."
|
||||
"select_verified_email": "Selecciona un correu electrònic verificat",
|
||||
"custom_reply_to_email_title": "Correu electrònic personalitzat de 'Respondre a'",
|
||||
"custom_reply_to_email_description": "Utilitza una adreça de correu electrònic diferent com a resposta per als correus de confirmació en lloc del correu de l'organitzador",
|
||||
"email_survey_triggered_by_workflow": "Aquesta enquesta va ser activada per un Workflow a Cal.",
|
||||
"skip_trial": "Salta el període de prova",
|
||||
"team_trials_skipped_successfully": "Períodes de prova d'equip saltats amb èxit",
|
||||
"sms_workflow_consent": "En introduir el teu número de telèfon, consents rebre missatges SMS per a aquest esdeveniment. Es poden aplicar tarifes de SMS.",
|
||||
"routing_preview_more_info_found_insights": "Podeu trobar més informació a <0>Estadístiques de rutes</0>",
|
||||
"results": "Resultats",
|
||||
"view_form": "Veure formulari",
|
||||
"sms_opt_out_message": "Envieu STOP per cancel·lar la subscripció als missatges SMS",
|
||||
"routing_form_next_in_queue": "{{count}} següent a la cua",
|
||||
"routing_form_select_members_to_email": "Enviar respostes per correu electrònic a",
|
||||
"routing_incomplete_booking_tab": "Reserves incompletes",
|
||||
"include_no_show_in_rr_calculation": "Incloure les reserves sense assistència en els càlculs de round robin",
|
||||
"matching": "Coincidència",
|
||||
"event_redirect": "Redirecció d'esdeveniments",
|
||||
"reset_form": "Restablir formulari",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Afegiu les vostres noves cadenes a dalt ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Vaše celé jméno",
|
||||
"no_name": "Žádné jméno",
|
||||
"enter_number_between_range": "Zadejte prosím číslo v rozpětí 1 a {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Rychlé a snadné - není potřeba účet. Ideální pro jednorázové schůzky.",
|
||||
"email_address": "E-mailová adresa",
|
||||
"enter_valid_email": "Zadejte platný e-mail",
|
||||
"please_schedule_future_call": "Naplánujte prosím budoucí hovor, pokud nebudeme dostupní za {{seconds}} sekund",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Osobně (adresa účastníka)",
|
||||
"somewhere_else": "Jiné místo",
|
||||
"custom_attendee_location": "Vlastní místo účastníka",
|
||||
"continue_as_guest": "Pokračovat jako host",
|
||||
"any_location": "Jakékoliv místo",
|
||||
"yes": "Ano",
|
||||
"no": "Ne",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Tým byl úspěšně aktualizován",
|
||||
"your_team_updated_successfully": "Váš tým byl úspěšně aktualizován.",
|
||||
"your_org_updated_successfully": "Vaše organizace byla aktualizována.",
|
||||
"error_copying_to_clipboard": "Chyba při kopírování do schránky",
|
||||
"about": "O aplikaci",
|
||||
"team_description": "Pár vět o vašem týmu. Objeví se na URL stránce vašeho týmu.",
|
||||
"organization_id": "ID organizace",
|
||||
"organization_id_copied": "ID organizace zkopírováno.",
|
||||
"org_description": "Několik vět o vaší organizaci. Zobrazí se na adrese URL vaší organizace.",
|
||||
"team_id": "ID týmu",
|
||||
"team_id_copied": "ID týmu zkopírováno.",
|
||||
"members": "Členové",
|
||||
"organization_members": "Členové organizace",
|
||||
"member": "Člen",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Opravdu chcete odstranit tohoto člena z týmu?",
|
||||
"confirm_disband_team": "Ano, rozpustit tým",
|
||||
"confirm_remove_member": "Ano, odebrat člena",
|
||||
"confirm_subscription_cancellation": "Ano, zrušit předplatné",
|
||||
"cancel_subscription": "Zrušit předplatné",
|
||||
"cancel_subscription_description": "Zrušením předplatného trvale deaktivujete váš současný plán. Tuto akci nelze vrátit zpět.",
|
||||
"remove_member": "Odebrat člena",
|
||||
"manage_your_team": "Správa týmu",
|
||||
"no_teams": "Zatím nemáte žádné týmy.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL vaší rezervační stránky",
|
||||
"booking_cancel_redirect_uri": "URL stránky, kde mohou uživatelé zrušit svou rezervaci",
|
||||
"booking_reschedule_redirect_uri": "URL stránky, kde mohou uživatelé přeplánovat svou rezervaci",
|
||||
"booking_conflict_error": "Tento termín již není k dispozici. Vraťte se prosím na předchozí stránku a vyberte jiný čas.",
|
||||
"open_invitations": "Otevřené pozvánky",
|
||||
"new_team": "Nový tým",
|
||||
"create_first_team_and_invite_others": "Vytvořte svůj první tým a pozvěte ostatní uživatele ke spolupráci.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Váš účet byl vytvořen pomocí Identity Providera.",
|
||||
"account_managed_by_identity_provider": "Váš účet spravuje {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Pro změnu e-mailu, hesla, dvoufázového ověřování apod. prosím přejděte do nastavení účtu {{provider}}.",
|
||||
"account_managed_by_identity_provider_error": "Váš účet je spravován jiným poskytovatelem identity. Zkuste se přihlásit pomocí {{provider}}.",
|
||||
"user_creation_error": "Chyba při vytváření nového uživatele. Zkuste to prosím znovu.",
|
||||
"signin_with_google": "Přihlásit se pomocí Googlu",
|
||||
"signin_with_saml": "Přihlásit se pomocí SAML",
|
||||
"signin_with_saml_oidc": "Přihlášení pomocí SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Máte hotovo!",
|
||||
"install_zapier_app": "Nejdřív si z App Store nainstalujte aplikaci Zapier.",
|
||||
"install_make_app": "Nejprve si nainstalujte aplikaci Make z obchodu s aplikacemi.",
|
||||
"app_installation": "Instalace aplikace",
|
||||
"app_not_installed": "Aplikace není nainstalována",
|
||||
"visit_our_app_store": "Omlouváme se, tato aplikace není nainstalována na vašem účtu. Navštivte náš obchod s aplikacemi a objevte tuto a další skvělé aplikace.",
|
||||
"connect_apple_server": "Připojit se k serveru Apple",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "při zrušení události",
|
||||
"after_hosts_cal_video_no_show": "Poté, co se hostitelé nepřipojili k video hovoru",
|
||||
"after_guests_cal_video_no_show": "Poté, co se hosté nepřipojili k video hovoru",
|
||||
"join_video_call": "Připojit se k videohovoru",
|
||||
"sign_in_to_cal_com": "Přihlaste se ke svému účtu Cal.com",
|
||||
"log_in_to_cal_com": "Přihlásit se do Cal.com",
|
||||
"track_your_meetings": "Sledujte své schůzky, dostávejte oznámení a efektivněji spravujte svůj rozvrh.",
|
||||
"choose_how_you_d_like_to_join_call": "Vyberte, jak se chcete připojit k tomuto hovoru",
|
||||
"new_event_trigger": "při rezervaci nové události",
|
||||
"email_host_action": "odeslání e-mailu hostiteli",
|
||||
"email_attendee_action": "odeslat e-mail účastníkům",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Vlastní",
|
||||
"reminder": "Upomínka",
|
||||
"rescheduled": "Změna termínu",
|
||||
"rescheduled_by": "Přeplánováno uživatelem",
|
||||
"original_booking": "Původní rezervace",
|
||||
"completed": "Dokončeno",
|
||||
"rating": "Hodnocení",
|
||||
"reminder_email": "Upomínka: událost {{eventType}} s uživatelem {{name}} dne {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "Pracovní postup {{workflowName}} byl {{offOn}}",
|
||||
"download_responses": "Stáhnout odpovědi",
|
||||
"download_responses_description": "Stáhněte si všechny odpovědi do formuláře ve formátu CSV.",
|
||||
"view_responses": "Zobrazit odpovědi",
|
||||
"download": "Stáhnout",
|
||||
"downloading": "Stahování",
|
||||
"download_recording": "Stáhnout nahrávku",
|
||||
"transcription_enabled": "Přepisy jsou nyní povoleny",
|
||||
"transcription_stopped": "Přepisy byly zastaveny",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Přidání nového formuláře do vašeho týmu",
|
||||
"create_your_first_route": "Vytvořte svoje první směrování",
|
||||
"route_to_the_right_person": "Nasměrovat té správné osobě na základě odpovědí ve vašem formuláři",
|
||||
"form": "Formulář",
|
||||
"form_description": "Vytvořte vlastní formulář, který adresujete rezervující osobě",
|
||||
"copy_link_to_form": "Kopírovat odkaz na formulář",
|
||||
"theme": "Motiv stránky pro rezervace",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Nesprávný ověřovací kód",
|
||||
"not_verified": "Zatím neověřeno",
|
||||
"no_availability_in_month": "Žádná dostupnost pro {{month}}",
|
||||
"no_availability_rolling": "Plánování je dostupné pouze {{days}} dní dopředu. Zkontrolujte to prosím brzy znovu.",
|
||||
"no_availability_range": "Plánování skončilo dne {{date}}. Zkontrolujte prosím brzy znovu.",
|
||||
"view_previous_month": "Zobrazit předchozí měsíc",
|
||||
"view_next_month": "Zobrazit další měsíc",
|
||||
"send_code": "Odeslat kód",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Platba za tuto událost již není možná",
|
||||
"booking_with_payment_cancelled_already_paid": "Vrácení peněz za tuto rezervační platbu je na cestě.",
|
||||
"booking_with_payment_cancelled_refunded": "Tato rezervační platba byla vrácena.",
|
||||
"booking_with_payment_cancelled_no_refund": "Podle pravidel pro vrácení peněz této události není platba za rezervaci vratná.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Lhůta pro vrácení peněz za událost vypršela. Proto platba za rezervaci není vratná.",
|
||||
"booking_confirmation_failed": "Potvrzení rezervace se nezdařilo",
|
||||
"not_enough_seats": "Nedostatek míst",
|
||||
"form_builder_field_already_exists": "Pole s tímto názvem již existuje",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Otevřít dostupnost uživatelů",
|
||||
"organization_no_slots_notification_switch_title": "Dostávejte upozornění, když váš tým nemá žádnou dostupnost",
|
||||
"organization_no_slots_notification_switch_description": "Administrátoři budou dostávat e-mailová upozornění, když se uživatel pokusí rezervovat člena týmu a zjistí, že není žádná dostupnost. Tento e-mail spustíme po dvou výskytech a připomeneme vám to každých 7 dní na uživatele.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Zakázat SMS oznámení pro typy událostí pouze s telefonem",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Zakázat automatická SMS oznámení pro typy událostí, které vyžadují pouze telefonní číslo (attendeePhoneNumber) jako povinnou otázku s e-mailem jako volitelným nebo nevyžadovaným",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} vás přidal(a) do organizace {{team}} na {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} vás pozval(a) k připojení do organizace {{team}} na {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} vás přidal(a) do týmu {{team}} v organizaci {{parentTeamName}} na {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Váš odkaz byl změněn z {{a0}} na {{a1}}, ale nebojte se, všechny předchozí odkazy stále fungují a správně přesměrovávají. <br /><br />Upozorňujeme: Všechny vaše osobní typy událostí byly přesunuty do organizace <strong>{{teamName}}</strong>, což může zahrnovat i potenciální osobní odkaz.<br /><br />Přihlaste se a ujistěte se, že na svém novém organizačním účtu nemáte žádné soukromé události.<br /><br />Pro osobní události doporučujeme vytvořit nový účet s osobní e-mailovou adresou.<br /><br />Užijte si svůj nový čistý odkaz: {{a2}}",
|
||||
"email_organization_created|subject": "Vaše organizace byla vytvořena",
|
||||
"your_current_plan": "Váš aktuální plán",
|
||||
"organization_price_per_user_month": "$37 za uživatele měsíčně (minimálně 30 míst)",
|
||||
"organization_price_per_user_month": "$37 za uživatele za měsíc",
|
||||
"privacy_organization_description": "Spravujte nastavení soukromí pro vaši organizaci",
|
||||
"privacy": "Ochrana soukromí",
|
||||
"team_will_be_under_org": "Nové týmy budou pod vaší organizací",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Pokračováním souhlasíte s našimi",
|
||||
"terms": "Podmínkami",
|
||||
"always_show_x_days": "Vždy dostupné {{x}} dní",
|
||||
"team_subscription_cancelled_successfully": "Předplatné týmu bylo úspěšně zrušeno",
|
||||
"team_subscription_cancellation_error": "Chyba při rušení předplatného týmu",
|
||||
"unable_to_subscribe_to_the_platform": "Při pokusu o přihlášení k plánu platformy došlo k chybě, zkuste to prosím znovu později",
|
||||
"updating_oauth_client_error": "Při aktualizaci OAuth klienta došlo k chybě, zkuste to prosím znovu později",
|
||||
"creating_oauth_client_error": "Při vytváření OAuth klienta došlo k chybě, zkuste to prosím znovu později",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Přeskočit vytvoření záznamu {{entry}}, pokud neexistuje v Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Pokud kontakt neexistuje pod účtem, vytvořte nový lead z účastníka",
|
||||
"salesforce_create_new_contact_under_account": "Vytvořte nový kontakt pod účtem na základě e-mailové domény účastníka a existujících kontaktů",
|
||||
"salesforce_change_record_owner_on_booking": "Změnit vlastníka záznamu při rezervaci",
|
||||
"mass_assign_attributes": "Hromadné přiřazení atributů",
|
||||
"reroute_preview_custom_message": "Výsledkem je zobrazení vlastní zprávy. Zkuste změnit odpověď na přesměrování na událost",
|
||||
"reroute_preview_external_redirect": "Výsledkem je přesměrování na {{externalUrl}}. Zkuste změnit odpověď na přesměrování na událost",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Přesměrováno za období",
|
||||
"per_day": "Za den",
|
||||
"per_week": "Za týden",
|
||||
"per_month": "Za měsíc",
|
||||
"per_month": "za měsíc",
|
||||
"routing_form_insights_assignment_reason": "Důvod přiřazení",
|
||||
"access_denied": "Přístup odepřen",
|
||||
"salesforce_route_to_owner": "Vlastník kontaktu bude hostem Round Robin, pokud je k dispozici",
|
||||
"salesforce_add_attendees_as": "Přidat nové účastníky jako",
|
||||
"salesforce_do_not_route_to_owner": "Vlastník kontaktu nebude nucen (stále může být hostem, pokud odpovídá atributům a kritériím Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Přiřadit uživateli, který odpovídá vyhledávacímu poli na účtu",
|
||||
"salesforce_option": "Možnost Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Nedostatek",
|
||||
"routing_form": "Směrovací formulář",
|
||||
"go_back_and_save": "Vrátit se a uložit",
|
||||
"save_changes": "Uložit změny",
|
||||
"leave_without_saving": "Odejít bez uložení",
|
||||
"leave_without_saving_description": "Opravdu chcete odejít bez uložení změn ve vašem směrovacím formuláři?",
|
||||
"something_unexpected_occurred": "Došlo k neočekávané chybě",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autorizovat",
|
||||
"next": "Další",
|
||||
"hide": "Skrýt",
|
||||
"show": "Zobrazit",
|
||||
"utm_params": "UTM parametry",
|
||||
"no_utm_params": "Žádné UTM parametry nejsou k dispozici.",
|
||||
"asc": "Vzestupně",
|
||||
"desc": "Sestupně",
|
||||
"verify_email_change": "Ověřit změnu e-mailu",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Musíte mít minimální počet publikovaných týmů",
|
||||
"you_are_part_of_this_organization_already": "Již jste součástí této organizace",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Jste součástí jiné organizace, nelze vytvořit novou organizaci",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Jste součástí jiné platformové organizace, nelze vytvořit novou organizaci",
|
||||
"organization_payment_success": "Platba za organizaci byla úspěšná",
|
||||
"organization_payment_success_description": "Vaše organizace byla úspěšně vytvořena",
|
||||
"this_may_take_a_few_seconds": "Toto může trvat několik sekund...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Úvodní zaškolení organizace již bylo dokončeno",
|
||||
"organization_onboarding_already_exists": "Úvodní zaškolení organizace již existuje",
|
||||
"organization_onboarding_not_found": "Úvodní zaškolení organizace nebylo nalezeno",
|
||||
"payment_successful": "Platba byla úspěšná",
|
||||
"payment_successful": "Platba úspěšná!",
|
||||
"handover_onboarding_page_title": "Předání úvodního zaškolení",
|
||||
"handover_onboarding_page_description": "Předání úvodního zaškolení uživateli",
|
||||
"organization_already_exists_with_this_slug": "Organizace s tímto slugem již existuje",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Odkaz",
|
||||
"rows_per_page": "řádků na stránku",
|
||||
"pagination_status": "{{currentRange}} z {{totalItems}}",
|
||||
"tip_username_plus": "Tip: Mezi uživatelská jména můžete vložit '+': cal.com/anna+brian pro vytvoření dynamické skupinové schůzky",
|
||||
"tip_username_plus": "Tip: Mezi uživatelská jména můžete přidat '+': cal.com/anna+brian pro vytvoření dynamické skupinové schůzky",
|
||||
"user_has_no_team_yet": "Zatím nemáte žádný tým",
|
||||
"no_team_members": "Zatím nemáte žádné členy týmu",
|
||||
"recurring_event_doesnt_support_seats": "Opakující se událost nepodporuje funkci míst. Změňte ji na neopakující se pro povolení míst.",
|
||||
"seats_doesnt_support_recurring": "Funkce míst nepodporuje opakující se události. Zakažte funkci míst pro vytvoření opakující se události.",
|
||||
"recurring_event_seats_error": "Opakující se událost nepodporuje funkci míst. Zakažte funkci míst nebo změňte událost na neopakující se.",
|
||||
"segment": "Segment",
|
||||
"rename": "Přejmenovat",
|
||||
"rename_segment": "Přejmenovat segment",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Nejčastěji zrušené rezervace",
|
||||
"name_or_email": "Jméno nebo e-mail",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Pokud není nalezen žádný kontakt, použít vlastníka leadu, pokud existuje",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Datum a čas",
|
||||
"email_reminder_upcoming_event_notice" : "Toto je připomínka vaší nadcházející události.",
|
||||
"email_reminder_triggered_by_workflow" : "Toto připomenutí bylo spuštěno pracovním postupem v Cal.",
|
||||
"enable_delegation_credential": "Povolit delegované pověření",
|
||||
"enable_delegation_credential_description": "Udělte Cal.com automatický přístup ke kalendářům všech členů organizace povolením delegovaného pověření.",
|
||||
"disable_delegation_credential": "Zakázat delegované pověření",
|
||||
"disable_delegation_credential_description": "Jakmile je delegované pověření zakázáno, členové organizace, kteří nepropojili své kalendáře, to budou muset udělat ručně.",
|
||||
"last_active": "Naposledy aktivní",
|
||||
"member_since": "Členem od",
|
||||
"last_updated": "Naposledy aktualizováno",
|
||||
"salesforce_on_cancel_write_to_event": "Při zrušení rezervace zapsat do záznamu události místo smazání události",
|
||||
"salesforce_on_every_cancellation": "Při každém zrušení",
|
||||
"report_issue": "Nahlásit problém",
|
||||
"report_issue_description": "Můžete odeslat ticket na GitHubu nebo upgradovat svůj plán pro získání podpory v reálném čase s vývojářskými konferencemi",
|
||||
"open_issue": "Otevřít problém",
|
||||
"this_is_your_current_plan": "Toto je váš aktuální plán",
|
||||
"schedule_a_time": "Naplánovat čas",
|
||||
"this_includes": "Toto zahrnuje:",
|
||||
"oauth_client_updated_successfully": "OAuth klient byl úspěšně aktualizován",
|
||||
"oauth_client_not_found": "OAuth klient nebyl nalezen.",
|
||||
"subscribe_to_platform": "Přihlásit se k odběru platformy",
|
||||
"error_accessing_webhooks": "Chyba při pokusu o přístup k webhookům.",
|
||||
"webhook_update_failed": "Aktualizace webhooku se nezdařila.",
|
||||
"webhook_create_failed": "Vytvoření webhooku se nezdařilo.",
|
||||
"invalid_link": "Neplatný odkaz",
|
||||
"currently_subscribed_to_plan": "Aktuálně máte předplacený plán {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Uživatel/Tým",
|
||||
"client_id_copied": "ID klienta zkopírováno!",
|
||||
"client_secret_copied": "Tajný klíč klienta zkopírován!",
|
||||
"maintenance_message": "Tým Cal.com provádí plánovanou údržbu. Pokud máte jakékoli dotazy, kontaktujte podporu.",
|
||||
"your_payment_failed": "Vaše platba se nezdařila",
|
||||
"check_your_inbox": "Zkontrolujte svou e-mailovou schránku",
|
||||
"account_created_premium_not_reserved": "Váš účet byl vytvořen, ale vaše prémiové uživatelské jméno nebylo rezervováno.",
|
||||
"email_sent_with_activation_link": "Poslali jsme e-mail na adresu {{email}} s odkazem pro aktivaci vašeho účtu.",
|
||||
"activate_account_to_purchase_username": "Jakmile aktivujete svůj účet, budete moci znovu zkusit zakoupit své prémiové uživatelské jméno nebo vybrat jiné.",
|
||||
"open_in_gmail": "Otevřít v Gmailu",
|
||||
"dont_see_email": "Nevidíte e-mail?",
|
||||
"resend_in_seconds": "Znovu odeslat za {{seconds}} sekund",
|
||||
"resend": "Znovu odeslat",
|
||||
"verification_email_sent": "Ověřovací e-mail odeslán",
|
||||
"select_all_members": "Vybrat všechny členy",
|
||||
"select_all_members_tooltip": "Výběr všech členů přidá všechny budoucí členy týmu, když budou přidáni do týmu.",
|
||||
"form_settings": "Nastavení formuláře",
|
||||
"remove_whitelist_status": "Odebrat status na whitelist",
|
||||
"whitelist_user_workflows": "Přidat uživatelské workflow na whitelist",
|
||||
"user_workflows_whitelisted": "Uživatelské workflow přidáno na whitelist",
|
||||
"user_workflows_unwhitelisted": "Uživatelské workflow odebráno z whitelist",
|
||||
"date_and_time": "Datum a čas",
|
||||
"email_reminder_upcoming_event_notice": "Toto je připomínka vaší nadcházející události.",
|
||||
"email_reminder_triggered_by_workflow": "Toto připomenutí bylo spuštěno pracovním postupem v Cal.",
|
||||
"event_upper_case": "Událost",
|
||||
"scheduling_by": "Plánování podle",
|
||||
"experience_review_prompt": "Jaké byly vaše nedávné zkušenosti?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Jak jste spokojeni s vaším posledním jednáním?",
|
||||
"meeting_not_joined_question": "nejste se zúčastnili schůzky?",
|
||||
"reschedule_cta_short": "Přeplánujte zde.",
|
||||
"hide_organizer_email": "Skrýt e-mail organizátora",
|
||||
"platform_customer_cant_create_organization": "Jste již součástí platformní organizace, proto nemůžete vytvořit novou organizaci. Každý uživatel může patřit pouze do jedné organizace. Vytvořte si prosím nový účet cal.com s jiným e-mailem a použijte tento účet k předplacení organizačního plánu.",
|
||||
"organization_customer_cant_create_platform": "Jste již součástí organizace, proto nemůžete vytvořit platformní organizaci. Každý uživatel může patřit pouze do jedné organizace. Vytvořte si prosím nový účet cal.com s jiným e-mailem a použijte tento účet k předplacení platformního plánu.",
|
||||
"hide_organizer_email_description": "Skrýt e-mailovou adresu organizátora na obrazovce rezervace, v e-mailových oznámeních a událostech kalendáře",
|
||||
"you_and_conjunction": "Vy &",
|
||||
"email_survey_triggered_by_workflow": "Tento průzkum byl spuštěn pracovním postupem v Cal."
|
||||
"select_verified_email": "Vyberte ověřený e-mail",
|
||||
"custom_reply_to_email_title": "Vlastní e-mail pro odpověď",
|
||||
"custom_reply_to_email_description": "Použít jinou e-mailovou adresu jako adresu pro odpověď v potvrzovacích e-mailech místo e-mailu organizátora",
|
||||
"email_survey_triggered_by_workflow": "Tento průzkum byl spuštěn pracovním postupem v Cal.",
|
||||
"skip_trial": "Přeskočit zkušební období",
|
||||
"team_trials_skipped_successfully": "Zkušební období týmu úspěšně přeskočeno",
|
||||
"sms_workflow_consent": "Zadáním svého telefonního čísla souhlasíte s přijímáním SMS zpráv pro tuto událost. Mohou být účtovány poplatky za SMS.",
|
||||
"routing_preview_more_info_found_insights": "Více informací najdete v <0>Přehledu směrování</0>",
|
||||
"results": "Výsledky",
|
||||
"view_form": "Zobrazit formulář",
|
||||
"sms_opt_out_message": "Odešlete STOP pro odhlášení z SMS zpráv",
|
||||
"routing_form_next_in_queue": "{{count}} další ve frontě",
|
||||
"routing_form_select_members_to_email": "Odeslat e-mailové odpovědi na",
|
||||
"routing_incomplete_booking_tab": "Nedokončené rezervace",
|
||||
"include_no_show_in_rr_calculation": "Zahrnout nedostavené rezervace do výpočtů round robin",
|
||||
"matching": "Odpovídající",
|
||||
"event_redirect": "Přesměrování události",
|
||||
"reset_form": "Resetovat formulář",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Dit fulde navn",
|
||||
"no_name": "Intet navn",
|
||||
"enter_number_between_range": "Indtast venligst et nummer mellem 1 og {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Hurtigt og nemt - ingen konto nødvendig. Perfekt til engangsmøder.",
|
||||
"email_address": "E-mail adresse",
|
||||
"enter_valid_email": "Indtast venligst en gyldig e-mail",
|
||||
"please_schedule_future_call": "Planlæg venligst et fremtidigt opkald, hvis vi ikke er tilgængelige om {{seconds}} sekunder",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Personlig (Deltageradresse)",
|
||||
"somewhere_else": "Et andet sted",
|
||||
"custom_attendee_location": "Brugerdefineret deltagerlokation",
|
||||
"continue_as_guest": "Fortsæt som gæst",
|
||||
"any_location": "Enhver lokation",
|
||||
"yes": "Ja",
|
||||
"no": "Nej",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Team opdateret",
|
||||
"your_team_updated_successfully": "Dit team er blevet opdateret.",
|
||||
"your_org_updated_successfully": "Din organisation er blevet opdateret med succes.",
|
||||
"error_copying_to_clipboard": "Fejl ved kopiering til udklipsholder",
|
||||
"about": "Om",
|
||||
"team_description": "Et par sætninger om dit team. Dette vil blive vist på dit teams url side.",
|
||||
"organization_id": "Organisations-ID",
|
||||
"organization_id_copied": "Organisations-ID kopieret.",
|
||||
"org_description": "Et par sætninger om din organisation. Dette vil fremgå på din organisations URL-side.",
|
||||
"team_id": "Team-ID",
|
||||
"team_id_copied": "Team-ID kopieret.",
|
||||
"members": "Medlemmer",
|
||||
"organization_members": "Organisationsmedlemmer",
|
||||
"member": "Medlem",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Er du sikker på du vil fjerne dette medlem fra teamet?",
|
||||
"confirm_disband_team": "Ja, opløs holdet",
|
||||
"confirm_remove_member": "Ja, fjern medlem",
|
||||
"confirm_subscription_cancellation": "Ja, annuller abonnement",
|
||||
"cancel_subscription": "Annuller abonnement",
|
||||
"cancel_subscription_description": "Annullering af dit abonnement vil permanent deaktivere din nuværende plan. Denne handling kan ikke fortrydes.",
|
||||
"remove_member": "Fjern medlem",
|
||||
"manage_your_team": "Administrér dit team",
|
||||
"no_teams": "Du har ikke nogen teams endnu.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL til din bookingside",
|
||||
"booking_cancel_redirect_uri": "URL til siden hvor dine brugere kan aflyse deres booking",
|
||||
"booking_reschedule_redirect_uri": "URL til siden hvor dine brugere kan ombooke deres aftale",
|
||||
"booking_conflict_error": "Denne tid er ikke længere tilgængelig. Gå tilbage til den forrige side og vælg et andet tidspunkt.",
|
||||
"open_invitations": "Åbne Invitationer",
|
||||
"new_team": "Nyt Team",
|
||||
"create_first_team_and_invite_others": "Opret dit første team og inviter andre brugere til at arbejde sammen.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Din konto blev oprettet ved hjælp af en Identitetsudbyder.",
|
||||
"account_managed_by_identity_provider": "Din konto administreres af {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "For at ændre din e-mail, adgangskode, aktivere to-faktor autentificering og mere, besøg venligst dine {{provider}} kontoindstillinger.",
|
||||
"account_managed_by_identity_provider_error": "Din konto administreres af en anden identitetsudbyder. Prøv at logge ind med {{provider}}.",
|
||||
"user_creation_error": "Fejl ved oprettelse af ny bruger. Prøv igen.",
|
||||
"signin_with_google": "Log ind med Google",
|
||||
"signin_with_saml": "Log ind med SAML",
|
||||
"signin_with_saml_oidc": "Log ind med SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Du er klar!",
|
||||
"install_zapier_app": "Du skal først installere Zapier appen i App Store.",
|
||||
"install_make_app": "Installer venligst først Make-appen i app-butikken.",
|
||||
"app_installation": "Appinstallation",
|
||||
"app_not_installed": "App ikke installeret",
|
||||
"visit_our_app_store": "Beklager, denne app er ikke installeret på din konto. Besøg venligst vores app-butik for at udforske og opdage denne og andre fantastiske apps.",
|
||||
"connect_apple_server": "Forbind til Apple Server",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "når begivenheden er aflyst",
|
||||
"after_hosts_cal_video_no_show": "Efter værterne ikke deltog i cal-videomødet",
|
||||
"after_guests_cal_video_no_show": "Efter gæsterne ikke deltog i cal-videomødet",
|
||||
"join_video_call": "Deltag i videoopkaldet",
|
||||
"sign_in_to_cal_com": "Log ind på din Cal.com-konto",
|
||||
"log_in_to_cal_com": "Log ind på Cal.com",
|
||||
"track_your_meetings": "Følg dine møder, få notifikationer og administrer din tidsplan mere effektivt.",
|
||||
"choose_how_you_d_like_to_join_call": "Vælg, hvordan du vil deltage i dette opkald",
|
||||
"new_event_trigger": "når ny begivenhed er booket",
|
||||
"email_host_action": "send e-mail til vært",
|
||||
"email_attendee_action": "send e-mail til deltagere",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Brugerdefineret",
|
||||
"reminder": "Påmindelse",
|
||||
"rescheduled": "Omplanlagt",
|
||||
"rescheduled_by": "Omplanlagt af",
|
||||
"original_booking": "Oprindelig booking",
|
||||
"completed": "Fuldført",
|
||||
"rating": "Bedømmelse",
|
||||
"reminder_email": "Påmindelse: {{eventType}} med {{name}} den {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}} workflow er nu slået {{offOn}}",
|
||||
"download_responses": "Download Svar",
|
||||
"download_responses_description": "Download alle svar på din formular i CSV-format.",
|
||||
"view_responses": "Se svar",
|
||||
"download": "Download",
|
||||
"downloading": "Downloader",
|
||||
"download_recording": "Download optagelse",
|
||||
"transcription_enabled": "Transskriptioner er nu aktiveret",
|
||||
"transcription_stopped": "Transskriptioner er nu stoppet",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Tilføj ny formular til dit team",
|
||||
"create_your_first_route": "Opret din første rute",
|
||||
"route_to_the_right_person": "Rute til den rette person baseret på svarene på din formular",
|
||||
"form": "Formular",
|
||||
"form_description": "Opret din formular for at rute en booker",
|
||||
"copy_link_to_form": "Kopiér link til formular",
|
||||
"theme": "Tema for bookingside",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Forkert bekræftelseskode",
|
||||
"not_verified": "Endnu ikke bekræftet",
|
||||
"no_availability_in_month": "Ingen tilgængelighed i {{month}}",
|
||||
"no_availability_rolling": "Planlægning er kun tilgængelig op til {{days}} dage i forvejen. Kom snart tilbage.",
|
||||
"no_availability_range": "Planlægning sluttede den {{date}}. Tjek venligst igen snart.",
|
||||
"view_previous_month": "Se forrige måned",
|
||||
"view_next_month": "Vis næste måned",
|
||||
"send_code": "Send kode",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Det er ikke længere muligt at betale for denne begivenhed",
|
||||
"booking_with_payment_cancelled_already_paid": "En tilbagebetaling for denne booking betaling er på vej.",
|
||||
"booking_with_payment_cancelled_refunded": "Denne booking betaling er blevet refunderet.",
|
||||
"booking_with_payment_cancelled_no_refund": "I henhold til arrangementets refunderingspolitik er betalingen for bookingen ikke refunderbar.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Arrangementets refunderingsperiode er udløbet. Derfor er betalingen for bookingen ikke refunderbar.",
|
||||
"booking_confirmation_failed": "Reservationsbekræftelse mislykkedes",
|
||||
"not_enough_seats": "Ikke nok pladser",
|
||||
"form_builder_field_already_exists": "Et felt med dette navn findes allerede",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Åbn brugernes tilgængelighed",
|
||||
"organization_no_slots_notification_switch_title": "Få besked, når dit team ikke har nogen tilgængelighed",
|
||||
"organization_no_slots_notification_switch_description": "Administratorer vil få e-mailbeskeder, når en bruger forsøger at booke et teammedlem og møder 'Ingen tilgængelighed'. Vi udløser denne e-mail efter to forekomster og minder dig om det hver 7. dag pr. bruger.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Deaktiver SMS-notifikationer for kun telefonbaserede begivenhedstyper",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Deaktiver automatiske SMS-notifikationer for begivenhedstyper, der kun har telefonnummer (attendeePhoneNumber) som obligatorisk spørgsmål, hvor e-mail er valgfri eller ikke påkrævet",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} har tilføjet dig til organisationen {{team}} på {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} har inviteret dig til at deltage i organisationen {{team}} på {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} har tilføjet dig til teamet {{team}} i organisationen {{parentTeamName}} på {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Dit link er blevet ændret fra {{a0}} til {{a1}}, men bare rolig, alle tidligere links fungerer stadig og omdirigerer korrekt. <br /><br />Bemærk venligst: Alle dine personlige begivenhedstyper er blevet flyttet til <strong>{{teamName}}</strong> organisationen, hvilket også kan omfatte potentielle personlige links.<br /><br />Log venligst ind og sørg for, at du ikke har private begivenheder på din nye organisationskonto.<br /><br />Til personlige begivenheder anbefaler vi at oprette en ny konto med en personlig e-mailadresse.<br /><br />Nyd dit nye rene link: {{a2}}",
|
||||
"email_organization_created|subject": "Din organisation er blevet oprettet",
|
||||
"your_current_plan": "Din nuværende plan",
|
||||
"organization_price_per_user_month": "$37 per bruger pr. måned (minimum 30 pladser)",
|
||||
"organization_price_per_user_month": "$37 pr. bruger pr. måned",
|
||||
"privacy_organization_description": "Administrer privatlivsindstillinger for din organisation",
|
||||
"privacy": "Privatliv",
|
||||
"team_will_be_under_org": "Nye teams vil være under din organisation",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Ved at fortsætte accepterer du vores",
|
||||
"terms": "Vilkår",
|
||||
"always_show_x_days": "Vis altid {{x}} dage tilgængelige",
|
||||
"team_subscription_cancelled_successfully": "Teamabonnement annulleret med succes",
|
||||
"team_subscription_cancellation_error": "Fejl under annullering af teamabonnement",
|
||||
"unable_to_subscribe_to_the_platform": "Der opstod en fejl under forsøget på at abonnere på platformplanen, prøv venligst igen senere",
|
||||
"updating_oauth_client_error": "Der opstod en fejl under opdatering af OAuth-klienten, prøv venligst igen senere",
|
||||
"creating_oauth_client_error": "Der opstod en fejl under oprettelse af OAuth-klienten, prøv venligst igen senere",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Spring oprettelse af {{entry}}-post over, hvis de ikke findes i Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Hvis kontakten ikke findes under en konto, opret nyt lead fra deltager",
|
||||
"salesforce_create_new_contact_under_account": "Opret en ny kontakt under en konto baseret på deltagerens e-maildomæne og eksisterende kontakter",
|
||||
"salesforce_change_record_owner_on_booking": "Skift ejer af post ved booking",
|
||||
"mass_assign_attributes": "Masse tildel attributter",
|
||||
"reroute_preview_custom_message": "Det resulterer i at vise en tilpasset besked. Prøv at ændre svaret til at omdirigere til en begivenhed",
|
||||
"reroute_preview_external_redirect": "Det resulterer i en omdirigering til {{externalUrl}}. Prøv at ændre svaret til at omdirigere til en begivenhed",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Dirigeret til pr. periode",
|
||||
"per_day": "Pr. dag",
|
||||
"per_week": "Pr. uge",
|
||||
"per_month": "Pr. måned",
|
||||
"per_month": "pr. måned",
|
||||
"routing_form_insights_assignment_reason": "Tildelingsårsag",
|
||||
"access_denied": "Adgang nægtet",
|
||||
"salesforce_route_to_owner": "Kontaktens ejer vil være Round Robin-vært, hvis tilgængelig",
|
||||
"salesforce_add_attendees_as": "Tilføj nye deltagere som",
|
||||
"salesforce_do_not_route_to_owner": "Kontaktens ejer vil ikke blive tvunget (kan stadig være vært, hvis det matcher attributterne og Round Robin-kriterierne)",
|
||||
"salesforce_route_to_custom_lookup_field": "Rute til en bruger, der matcher et opslagfelt på en konto",
|
||||
"salesforce_option": "Salesforce-indstilling",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Underskud",
|
||||
"routing_form": "Routing-formular",
|
||||
"go_back_and_save": "Gå tilbage og gem",
|
||||
"save_changes": "Gem ændringer",
|
||||
"leave_without_saving": "Forlad uden at gemme",
|
||||
"leave_without_saving_description": "Er du sikker på, at du vil forlade siden uden at gemme ændringerne i din rutningsformular?",
|
||||
"something_unexpected_occurred": "Der opstod en uventet fejl",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Godkend",
|
||||
"next": "Næste",
|
||||
"hide": "Skjul",
|
||||
"show": "Vis",
|
||||
"utm_params": "UTM-parametre",
|
||||
"no_utm_params": "Ingen UTM-parametre tilgængelige.",
|
||||
"asc": "Stigende",
|
||||
"desc": "Faldende",
|
||||
"verify_email_change": "Bekræft ændring af e-mail",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Du skal have et minimum af offentliggjorte teams",
|
||||
"you_are_part_of_this_organization_already": "Du er allerede en del af denne organisation",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Du er en del af en anden organisation, kan ikke oprette en ny organisation",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Du er en del af en anden platformorganisation, kan ikke oprette en ny organisation",
|
||||
"organization_payment_success": "Organisationsbetaling gennemført",
|
||||
"organization_payment_success_description": "Din organisation er blevet oprettet med succes",
|
||||
"this_may_take_a_few_seconds": "Dette kan tage et par sekunder...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Organisationens onboarding er allerede gennemført",
|
||||
"organization_onboarding_already_exists": "Organisationens onboarding eksisterer allerede",
|
||||
"organization_onboarding_not_found": "Organisationens onboarding blev ikke fundet",
|
||||
"payment_successful": "Betaling gennemført",
|
||||
"payment_successful": "Betaling gennemført!",
|
||||
"handover_onboarding_page_title": "Overdragelse af onboarding",
|
||||
"handover_onboarding_page_description": "Overdragelse af onboarding til brugeren",
|
||||
"organization_already_exists_with_this_slug": "En organisation med dette slug findes allerede",
|
||||
@@ -3022,6 +3061,9 @@
|
||||
"tip_username_plus": "Tip: Du kan tilføje et '+' mellem brugernavne: cal.com/anna+brian for at lave et dynamisk gruppemøde",
|
||||
"user_has_no_team_yet": "Du har ikke et team endnu",
|
||||
"no_team_members": "Du har ikke nogen teammedlemmer endnu",
|
||||
"recurring_event_doesnt_support_seats": "Tilbagevendende begivenheder understøtter ikke sædefunktionen. Gør den ikke-tilbagevendende for at aktivere sæder.",
|
||||
"seats_doesnt_support_recurring": "Sædefunktionen understøtter ikke tilbagevendende begivenheder. Deaktiver sædefunktionen for at gøre den tilbagevendende.",
|
||||
"recurring_event_seats_error": "Tilbagevendende begivenheder understøtter ikke sædefunktionen. Deaktiver sædefunktionen eller gør begivenheden ikke-tilbagevendende.",
|
||||
"segment": "Segment",
|
||||
"rename": "Omdøb",
|
||||
"rename_segment": "Omdøb segment",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Flest annullerede bookinger",
|
||||
"name_or_email": "Navn eller e-mail",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Hvis ingen kontakt findes, fald tilbage til lead-ejeren, hvis denne eksisterer",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Tilføj dine nye strenge ovenfor her ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Dato og tid",
|
||||
"email_reminder_upcoming_event_notice" : "Dette er en påmindelse om din kommende begivenhed.",
|
||||
"email_reminder_triggered_by_workflow" : "Denne påmindelse blev udløst af en arbejdsgang i Cal.",
|
||||
"enable_delegation_credential": "Aktivér delegationslegitimation",
|
||||
"enable_delegation_credential_description": "Giv Cal.com automatisk adgang til kalendere for alle organisationsmedlemmer ved at aktivere delegationslegitimation.",
|
||||
"disable_delegation_credential": "Deaktiver delegationslegitimation",
|
||||
"disable_delegation_credential_description": "Når delegationslegitimation er deaktiveret, skal organisationsmedlemmer, der ikke har forbundet deres kalendere, gøre det manuelt.",
|
||||
"last_active": "Sidst aktiv",
|
||||
"member_since": "Medlem siden",
|
||||
"last_updated": "Sidst opdateret",
|
||||
"salesforce_on_cancel_write_to_event": "Ved aflyst booking, skriv til begivenhedsoptegnelsen i stedet for at slette begivenheden",
|
||||
"salesforce_on_every_cancellation": "Ved hver aflysning",
|
||||
"report_issue": "Rapportér problem",
|
||||
"report_issue_description": "Du kan indsende en ticket på GitHub eller opgradere din plan for at modtage realtidsstøtte med udviklerkonferencer",
|
||||
"open_issue": "Åbn problem",
|
||||
"this_is_your_current_plan": "Dette er din nuværende plan",
|
||||
"schedule_a_time": "Planlæg et tidspunkt",
|
||||
"this_includes": "Dette inkluderer:",
|
||||
"oauth_client_updated_successfully": "OAuth-klient opdateret med succes",
|
||||
"oauth_client_not_found": "OAuth-klient ikke fundet.",
|
||||
"subscribe_to_platform": "Abonner på platformen",
|
||||
"error_accessing_webhooks": "Fejl ved forsøg på at få adgang til webhooks.",
|
||||
"webhook_update_failed": "Kunne ikke opdatere webhook.",
|
||||
"webhook_create_failed": "Kunne ikke oprette webhook.",
|
||||
"invalid_link": "Ugyldigt link",
|
||||
"currently_subscribed_to_plan": "Du abonnerer i øjeblikket på {{planFirstLetter}}{{planRest}}-planen",
|
||||
"user_team": "Bruger/Team",
|
||||
"client_id_copied": "Klient-ID kopieret!",
|
||||
"client_secret_copied": "Klienthemmelighed kopieret!",
|
||||
"maintenance_message": "Cal.com-teamet udfører planlagt vedligeholdelse. Hvis du har spørgsmål, bedes du kontakte support.",
|
||||
"your_payment_failed": "Din betaling mislykkedes",
|
||||
"check_your_inbox": "Tjek din indbakke",
|
||||
"account_created_premium_not_reserved": "Din konto er blevet oprettet, men din premium er ikke blevet reserveret.",
|
||||
"email_sent_with_activation_link": "Vi har sendt en e-mail til {{email}} med et link til at aktivere din konto.",
|
||||
"activate_account_to_purchase_username": "Når du aktiverer din konto, vil du kunne prøve at købe dit premium-brugernavn igen eller vælge et andet.",
|
||||
"open_in_gmail": "Åbn i Gmail",
|
||||
"dont_see_email": "Kan du ikke se en e-mail?",
|
||||
"resend_in_seconds": "Send igen om {{seconds}} sekunder",
|
||||
"resend": "Send igen",
|
||||
"verification_email_sent": "Bekræftelses-e-mail sendt",
|
||||
"select_all_members": "Vælg alle medlemmer",
|
||||
"select_all_members_tooltip": "Hvis du vælger alle medlemmer, tilføjes alle fremtidige teammedlemmer, når de bliver en del af teamet.",
|
||||
"form_settings": "Formularindstillinger",
|
||||
"remove_whitelist_status": "Fjern whitelist-status",
|
||||
"whitelist_user_workflows": "Whitelist brugerarbejdsgange",
|
||||
"user_workflows_whitelisted": "Brugerarbejdsgange whitelisted",
|
||||
"user_workflows_unwhitelisted": "Brugerarbejdsgange fjernet fra whitelist",
|
||||
"date_and_time": "Dato og tid",
|
||||
"email_reminder_upcoming_event_notice": "Dette er en påmindelse om din kommende begivenhed.",
|
||||
"email_reminder_triggered_by_workflow": "Denne påmindelse blev udløst af en arbejdsgang i Cal.",
|
||||
"event_upper_case": "Begivenhed",
|
||||
"scheduling_by": "Planlægning af",
|
||||
"experience_review_prompt": "Hvordan var din seneste oplevelse?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Hvor tilfreds var du med dit seneste møde?",
|
||||
"meeting_not_joined_question": "deltog ikke i mødet?",
|
||||
"reschedule_cta_short": "Planlæg igen her.",
|
||||
"hide_organizer_email": "Skjul arrangørens e-mail",
|
||||
"platform_customer_cant_create_organization": "Du er allerede en del af en platformorganisation, og derfor kan du ikke oprette en ny organisation. Hver bruger kan kun tilhøre én organisation. Opret venligst en ny cal.com-konto med en anden e-mail og brug den konto til at abonnere på organisationsplanen.",
|
||||
"organization_customer_cant_create_platform": "Du er allerede en del af en organisation, og derfor kan du ikke oprette en platformorganisation. Hver bruger kan kun tilhøre én organisation. Opret venligst en ny cal.com-konto med en anden e-mail og brug den konto til at abonnere på platformplanen.",
|
||||
"hide_organizer_email_description": "Skjul arrangørens e-mailadresse fra bookingskærmen, e-mailnotifikationer og kalenderbegivenheder",
|
||||
"you_and_conjunction": "Du &",
|
||||
"email_survey_triggered_by_workflow": "Denne undersøgelse blev udløst af en Arbejdsgang i Cal."
|
||||
"select_verified_email": "Vælg en verificeret e-mail",
|
||||
"custom_reply_to_email_title": "Brugerdefineret 'Svar-til'-e-mail",
|
||||
"custom_reply_to_email_description": "Brug en anden e-mailadresse som svar-til for bekræftelses-e-mails i stedet for arrangørens e-mail",
|
||||
"email_survey_triggered_by_workflow": "Denne undersøgelse blev udløst af en Arbejdsgang i Cal.",
|
||||
"skip_trial": "Spring prøveperioden over",
|
||||
"team_trials_skipped_successfully": "Teamets prøveperioder blev springet over med succes",
|
||||
"sms_workflow_consent": "Ved at indtaste dit telefonnummer giver du samtykke til at modtage SMS-beskeder for denne begivenhed. SMS-takster kan gælde.",
|
||||
"routing_preview_more_info_found_insights": "Flere oplysninger kan findes i <0>Routing Insights</0>",
|
||||
"results": "Resultater",
|
||||
"view_form": "Vis formular",
|
||||
"sms_opt_out_message": "Send STOP for at framelde SMS-beskeder",
|
||||
"routing_form_next_in_queue": "{{count}} næste i køen",
|
||||
"routing_form_select_members_to_email": "Send e-mail-svar til",
|
||||
"routing_incomplete_booking_tab": "Ufuldstændige bookinger",
|
||||
"include_no_show_in_rr_calculation": "Inkluder udeblivelser i round robin-beregninger",
|
||||
"matching": "Matchning",
|
||||
"event_redirect": "Begivenheds-omdirigering",
|
||||
"reset_form": "Nulstil formular",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Tilføj dine nye strenge ovenfor her ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Ihr vollständiger Name",
|
||||
"no_name": "Kein Name",
|
||||
"enter_number_between_range": "Bitte geben Sie eine Zahl zwischen 1 und {{maxOccurences}} ein",
|
||||
"continue_as_guest_description": "Schnell und einfach - kein Konto erforderlich. Perfekt für einmalige Meetings.",
|
||||
"email_address": "E-Mail Adresse",
|
||||
"enter_valid_email": "Bitte geben Sie eine gültige Emaildresse ein",
|
||||
"please_schedule_future_call": " Bitte planen Sie einen Anruf in der Zukunft ein, falls wir nicht innerhalb von {{seconds}} Sekunden verfügbar sind",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Vor Ort (Adresse von Ihnen)",
|
||||
"somewhere_else": "Anderer Ort",
|
||||
"custom_attendee_location": "Benutzerdefinierter Teilnehmerort",
|
||||
"continue_as_guest": "Als Gast fortfahren",
|
||||
"any_location": "Beliebiger Ort",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Team erfolgreich aktualisiert",
|
||||
"your_team_updated_successfully": "Ihr Team wurde erfolgreich aktualisiert.",
|
||||
"your_org_updated_successfully": "Ihre Org wurde erfolgreich aktualisiert.",
|
||||
"error_copying_to_clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
||||
"about": "Beschreibung",
|
||||
"team_description": "Ein paar Sätze über Ihr Team auf der öffentlichen Teamseite.",
|
||||
"organization_id": "Organisations-ID",
|
||||
"organization_id_copied": "Organisations-ID kopiert.",
|
||||
"org_description": "Ein paar Sätze zu Ihrer Organisation. Dies wird auf der URL-Seite Ihrer Organisation erscheinen.",
|
||||
"team_id": "Team-ID",
|
||||
"team_id_copied": "Team-ID kopiert.",
|
||||
"members": "Mitglieder",
|
||||
"organization_members": "Mitglieder der Organization",
|
||||
"member": "Mitglied",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Sind Sie sicher, dass Sie dieses Mitglied aus dem Team entfernen möchten?",
|
||||
"confirm_disband_team": "Ja, Team auflösen",
|
||||
"confirm_remove_member": "Ja, Mitglied entfernen",
|
||||
"confirm_subscription_cancellation": "Ja, Abonnement kündigen",
|
||||
"cancel_subscription": "Abonnement kündigen",
|
||||
"cancel_subscription_description": "Durch die Kündigung Ihres Abonnements wird Ihr aktueller Plan dauerhaft deaktiviert. Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"remove_member": "Mitglied entfernen",
|
||||
"manage_your_team": "Team verwalten",
|
||||
"no_teams": "Sie haben noch keine Teams.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL Ihrer Buchungsseite",
|
||||
"booking_cancel_redirect_uri": "URL der Seite, auf der Ihre Nutzer ihre Buchung stornieren können",
|
||||
"booking_reschedule_redirect_uri": "URL der Seite, auf der Ihre Nutzer ihre Buchung umplanen können",
|
||||
"booking_conflict_error": "Dieser Zeitraum ist nicht mehr verfügbar. Bitte kehren Sie zur vorherigen Seite zurück und wählen Sie eine andere Zeit.",
|
||||
"open_invitations": "Offene Einladungen",
|
||||
"new_team": "Neues Team",
|
||||
"create_first_team_and_invite_others": "Erstellen Sie Ihr erstes Team und laden Sie andere Benutzer ein, zusammenzuarbeiten.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Ihr Konto wurde mit einem Identitäts-Anbieter erstellt.",
|
||||
"account_managed_by_identity_provider": "Ihr Konto wird verwaltet von {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Um Ihre E-Mail-Adresse, Ihr Passwort, die Zwei-Faktor-Authentifizierung und sonstiges zu ändern, besuchen Sie bitte Ihre {{provider}} -Kontoeinstellungen.",
|
||||
"account_managed_by_identity_provider_error": "Ihr Konto wird von einem anderen Identitätsanbieter verwaltet. Versuchen Sie, sich mit {{provider}} anzumelden.",
|
||||
"user_creation_error": "Fehler beim Erstellen eines neuen Benutzers. Bitte versuchen Sie es erneut.",
|
||||
"signin_with_google": "Mit Google anmelden",
|
||||
"signin_with_saml": "Anmelden mit SAML",
|
||||
"signin_with_saml_oidc": "Anmelden mit SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Du bist fertig!",
|
||||
"install_zapier_app": "Bitte installieren Sie zuerst die Zapier-App im App Store.",
|
||||
"install_make_app": "Bitte installieren Sie zuerst die Make-App im App Store.",
|
||||
"app_installation": "App-Installation",
|
||||
"app_not_installed": "App nicht installiert",
|
||||
"visit_our_app_store": "Entschuldigung, diese App ist nicht auf Ihrem Konto installiert. Bitte besuchen Sie unseren App-Store, um diese und andere großartige Apps zu entdecken und zu erkunden.",
|
||||
"connect_apple_server": "Mit Apple-Server verbinden",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "wenn der Termin abgesagt wird",
|
||||
"after_hosts_cal_video_no_show": "Nachdem die Gastgeber nicht am Cal-Video teilgenommen haben",
|
||||
"after_guests_cal_video_no_show": "Nachdem die Gäste nicht am Cal-Video teilgenommen haben",
|
||||
"join_video_call": "Am Videoanruf teilnehmen",
|
||||
"sign_in_to_cal_com": "Bei Ihrem Cal.com-Konto anmelden",
|
||||
"log_in_to_cal_com": "Bei Cal.com anmelden",
|
||||
"track_your_meetings": "Verfolgen Sie Ihre Meetings, erhalten Sie Benachrichtigungen und verwalten Sie Ihren Zeitplan effektiver.",
|
||||
"choose_how_you_d_like_to_join_call": "Wählen Sie, wie Sie an diesem Anruf teilnehmen möchten",
|
||||
"new_event_trigger": "wenn ein neuer Termin gebucht wird",
|
||||
"email_host_action": "E-Mail an den Veranstalter senden",
|
||||
"email_attendee_action": "E-Mail an Teilnehmende senden",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Benutzerdefiniert",
|
||||
"reminder": "Erinnerung",
|
||||
"rescheduled": "Neu geplant",
|
||||
"rescheduled_by": "Neu geplant von",
|
||||
"original_booking": "Ursprüngliche Buchung",
|
||||
"completed": "Erledigt",
|
||||
"rating": "Bewertung",
|
||||
"reminder_email": "Erinnerung: {{eventType}} mit {{name}} bei {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}} Workflow erfolgreich {{offOn}}geschaltet",
|
||||
"download_responses": "Antworten herunterladen",
|
||||
"download_responses_description": "Laden Sie alle Antworten zu Ihrem Formular im CSV-Format herunter.",
|
||||
"view_responses": "Antworten anzeigen",
|
||||
"download": "Herunterladen",
|
||||
"downloading": "Wird heruntergeladen",
|
||||
"download_recording": "Aufnahme herunterladen",
|
||||
"transcription_enabled": "Transkriptionen sind jetzt aktiviert",
|
||||
"transcription_stopped": "Transkriptionen werden jetzt gestoppt",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Neues Formular zu Ihrem Team hinzufügen",
|
||||
"create_your_first_route": "Erstellen Sie Ihre erste Weiterleitung",
|
||||
"route_to_the_right_person": "Anhand der Formularantworten an die richtige Person weiterleiten",
|
||||
"form": "Formular",
|
||||
"form_description": "Erstellen Sie Ihr Formular, um einen Bucher zu anzuleiten",
|
||||
"copy_link_to_form": "Link in Formular kopieren",
|
||||
"theme": "Design der Buchungsseite",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Bestätigungscode falsch",
|
||||
"not_verified": "Noch nicht bestätigt",
|
||||
"no_availability_in_month": "Keine Verfügbarkeit im {{month}}",
|
||||
"no_availability_rolling": "Terminplanung ist nur bis zu {{days}} im Voraus verfügbar. Bitte schauen Sie bald wieder vorbei.",
|
||||
"no_availability_range": "Die Terminplanung endete am {{date}}. Bitte schauen Sie bald wieder vorbei.",
|
||||
"view_previous_month": "Vormonat anzeigen",
|
||||
"view_next_month": "Nächsten Monat anzeigen",
|
||||
"send_code": "Code senden",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Zahlung für dieses Ereignis ist nicht mehr möglich",
|
||||
"booking_with_payment_cancelled_already_paid": "Eine Rückerstattung für diese Buchungszahlung ist auf dem Weg.",
|
||||
"booking_with_payment_cancelled_refunded": "Diese Buchungszahlung wurde zurückerstattet.",
|
||||
"booking_with_payment_cancelled_no_refund": "Gemäß der Rückerstattungsrichtlinie des Events ist die Buchungszahlung nicht erstattungsfähig.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Das Rückerstattungsfenster für das Event ist abgelaufen. Daher ist die Buchungszahlung nicht erstattungsfähig.",
|
||||
"booking_confirmation_failed": "Buchungsbestätigung fehlgeschlagen",
|
||||
"not_enough_seats": "Nicht genügend Plätze",
|
||||
"form_builder_field_already_exists": "Ein Feld mit diesem Namen ist bereits vorhanden",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Benutzerverfügbarkeit öffnen",
|
||||
"organization_no_slots_notification_switch_title": "Erhalten Sie Benachrichtigungen, wenn Ihr Team keine Verfügbarkeiten hat",
|
||||
"organization_no_slots_notification_switch_description": "Admins erhalten E-Mail-Benachrichtigungen, wenn ein Benutzer versucht, ein Teammitglied zu buchen, und „Keine Verfügbarkeit“ sieht. Wir lösen diese E-Mail nach zwei Vorfällen aus und erinnern Sie alle 7 Tage pro Benutzer. ",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "SMS-Benachrichtigungen für reine Telefon-Eventtypen deaktivieren",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Automatische SMS-Benachrichtigungen für Eventtypen deaktivieren, die nur Telefonnummer (attendeePhoneNumber) als Pflichtfrage haben, wobei E-Mail optional oder nicht erforderlich ist",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} hat Sie zur Organisation {{team}} auf {{appName}} hinzugefügt",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} hat Sie eingeladen, der Organisation {{team}} auf {{appName}} beizutreten",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} hat Sie zum Team {{team}} der Organisation {{parentTeamName}} auf {{appName}} hinzugefügt",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Dein Link wurde von {{a0}} zu {{a1}} geändert, aber keine Sorge, alle vorherigen Links funktionieren weiterhin und leiten entsprechend weiter. <br /><br />Bitte beachte: Alle deine persönlichen Ereignistypen wurden in die <strong>{{teamName}}</strong> Organisation verschoben, was auch potenzielle persönliche Links einschließen kann.<br /><br />Bitte melde dich an und stelle sicher, dass du keine privaten Ereignisse in deinem neuen Organisationskonto hast.<br /><br />Für persönliche Ereignisse empfehlen wir, ein neues Konto mit einer persönlichen E-Mail-Adresse zu erstellen.<br /><br />Genieße deinen neuen übersichtlichen Link: {{a2}}",
|
||||
"email_organization_created|subject": "Ihre Organisation wurde erstellt",
|
||||
"your_current_plan": "Ihr aktueller Tarif",
|
||||
"organization_price_per_user_month": "37 $ pro Nutzer im Monat (mindestens 30 Sitzplätze)",
|
||||
"organization_price_per_user_month": "37 $ pro Benutzer pro Monat",
|
||||
"privacy_organization_description": "Privatsphäre-Einstellungen für Ihre Organisation verwalten",
|
||||
"privacy": "Datenschutz",
|
||||
"team_will_be_under_org": "Neue Teams werden unter Ihrer Organisation sein",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Indem Sie fortfahren, stimmen Sie unseren",
|
||||
"terms": "Nutzungsbedingungen",
|
||||
"always_show_x_days": "Immer für {{x}} Tage verfügbar",
|
||||
"team_subscription_cancelled_successfully": "Team-Abonnement erfolgreich gekündigt",
|
||||
"team_subscription_cancellation_error": "Fehler bei der Kündigung des Team-Abonnements",
|
||||
"unable_to_subscribe_to_the_platform": "Beim Abonnieren des Platform-Plans ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut",
|
||||
"updating_oauth_client_error": "Beim Aktualisieren des OAuth-Clients ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut",
|
||||
"creating_oauth_client_error": "Beim Erstellen des OAuth-Clients ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Überspringen Sie die Erstellung eines {{entry}}-Datensatzes, wenn dieser nicht in Salesforce existiert",
|
||||
"salesforce_if_account_does_not_exist": "Wenn der Kontakt nicht unter einem Account existiert, erstellen Sie einen neuen Lead aus dem Teilnehmer",
|
||||
"salesforce_create_new_contact_under_account": "Erstellen Sie einen neuen Kontakt unter einem Account basierend auf der E-Mail-Domain des Teilnehmers und bestehenden Kontakten",
|
||||
"salesforce_change_record_owner_on_booking": "Datensatzinhaber bei Buchung ändern",
|
||||
"mass_assign_attributes": "Attribute massenweise zuweisen",
|
||||
"reroute_preview_custom_message": "Es führt zur Anzeige einer benutzerdefinierten Nachricht. Versuchen Sie, die Antwort zu ändern, um zu einem Ereignis weiterzuleiten",
|
||||
"reroute_preview_external_redirect": "Es führt zur Weiterleitung auf {{externalUrl}}. Versuchen Sie, die Antwort zu ändern, um zu einem Ereignis weiterzuleiten",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Weitergeleitet pro Zeitraum",
|
||||
"per_day": "Pro Tag",
|
||||
"per_week": "Pro Woche",
|
||||
"per_month": "Pro Monat",
|
||||
"per_month": "pro Monat",
|
||||
"routing_form_insights_assignment_reason": "Zuweisungsgrund",
|
||||
"access_denied": "Zugriff verweigert",
|
||||
"salesforce_route_to_owner": "Der Kontaktinhaber wird der Round Robin Host sein, falls verfügbar",
|
||||
"salesforce_add_attendees_as": "Neue Teilnehmer hinzufügen als",
|
||||
"salesforce_do_not_route_to_owner": "Der Kontaktinhaber wird nicht erzwungen (kann trotzdem Host sein, wenn die Attribute und Round Robin Kriterien übereinstimmen)",
|
||||
"salesforce_route_to_custom_lookup_field": "Weiterleitung an einen Benutzer, der mit einem Lookup-Feld eines Accounts übereinstimmt",
|
||||
"salesforce_option": "Salesforce-Option",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Fehlmenge",
|
||||
"routing_form": "Routing-Formular",
|
||||
"go_back_and_save": "Zurück und speichern",
|
||||
"save_changes": "Änderungen speichern",
|
||||
"leave_without_saving": "Ohne speichern verlassen",
|
||||
"leave_without_saving_description": "Sind Sie sicher, dass Sie die Änderungen an Ihrem Routing-Formular nicht speichern möchten?",
|
||||
"something_unexpected_occurred": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autorisieren",
|
||||
"next": "Weiter",
|
||||
"hide": "Ausblenden",
|
||||
"show": "Anzeigen",
|
||||
"utm_params": "UTM-Parameter",
|
||||
"no_utm_params": "Keine UTM-Parameter verfügbar.",
|
||||
"asc": "Aufsteigend",
|
||||
"desc": "Absteigend",
|
||||
"verify_email_change": "E-Mail-Änderung bestätigen",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Sie müssen mindestens veröffentlichte Teams haben",
|
||||
"you_are_part_of_this_organization_already": "Sie sind bereits Teil dieser Organisation",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Sie sind Teil einer anderen Organisation und können keine neue Organisation erstellen",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Sie sind Teil einer anderen Plattformorganisation und können keine neue Organisation erstellen",
|
||||
"organization_payment_success": "Organisationszahlung erfolgreich",
|
||||
"organization_payment_success_description": "Ihre Organisation wurde erfolgreich erstellt",
|
||||
"this_may_take_a_few_seconds": "Dies kann einige Sekunden dauern...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Organisations-Onboarding bereits abgeschlossen",
|
||||
"organization_onboarding_already_exists": "Organisations-Onboarding existiert bereits",
|
||||
"organization_onboarding_not_found": "Organisations-Onboarding nicht gefunden",
|
||||
"payment_successful": "Zahlung erfolgreich",
|
||||
"payment_successful": "Zahlung erfolgreich!",
|
||||
"handover_onboarding_page_title": "Übergabe-Onboarding",
|
||||
"handover_onboarding_page_description": "Übergabe des Onboardings an den Benutzer",
|
||||
"organization_already_exists_with_this_slug": "Eine organisation mit diesem slug existiert bereits",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Link",
|
||||
"rows_per_page": "Zeilen pro Seite",
|
||||
"pagination_status": "{{currentRange}} von {{totalItems}}",
|
||||
"tip_username_plus": "Tipp: Sie können ein '+' zwischen Benutzernamen setzen: cal.com/anna+brian, um ein dynamisches Gruppenmeeting zu erstellen",
|
||||
"tip_username_plus": "Tipp: Sie können ein '+' zwischen Benutzernamen einfügen: cal.com/anna+brian, um ein dynamisches Gruppenmeeting zu erstellen",
|
||||
"user_has_no_team_yet": "Sie haben noch kein Team",
|
||||
"no_team_members": "Sie haben noch keine Teammitglieder",
|
||||
"recurring_event_doesnt_support_seats": "Wiederkehrende Events unterstützen die Sitzplatzfunktion nicht. Machen Sie es zu einem einmaligen Event, um Sitzplätze zu aktivieren.",
|
||||
"seats_doesnt_support_recurring": "Die Sitzplatzfunktion unterstützt keine wiederkehrenden Events. Deaktivieren Sie die Sitzplatzfunktion, um es wiederkehrend zu machen.",
|
||||
"recurring_event_seats_error": "Wiederkehrende Events unterstützen die Sitzplatzfunktion nicht. Deaktivieren Sie die Sitzplatzfunktion oder machen Sie das Event nicht wiederkehrend.",
|
||||
"segment": "Segment",
|
||||
"rename": "Umbenennen",
|
||||
"rename_segment": "Segment umbenennen",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Am häufigsten abgesagte Termine",
|
||||
"name_or_email": "Name oder E-Mail",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Wenn kein Kontakt gefunden wird, auf den Lead-Eigentümer zurückgreifen, falls vorhanden",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Fügen Sie Ihre neuen Code-Zeilen über dieser hinzu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Datum und Uhrzeit",
|
||||
"email_reminder_upcoming_event_notice" : "Dies ist eine Erinnerung an Ihre bevorstehende Veranstaltung.",
|
||||
"email_reminder_triggered_by_workflow" : "Diese Erinnerung wurde durch einen Workflow in Cal ausgelöst.",
|
||||
"enable_delegation_credential": "Delegierungsnachweis aktivieren",
|
||||
"enable_delegation_credential_description": "Gewähren Sie Cal.com automatischen Zugriff auf die Kalender aller Organisationsmitglieder, indem Sie den Delegierungsnachweis aktivieren.",
|
||||
"disable_delegation_credential": "Delegierungsnachweis deaktivieren",
|
||||
"disable_delegation_credential_description": "Sobald der Delegierungsnachweis deaktiviert ist, müssen Organisationsmitglieder, die ihre Kalender noch nicht verbunden haben, dies manuell tun.",
|
||||
"last_active": "Zuletzt aktiv",
|
||||
"member_since": "Mitglied seit",
|
||||
"last_updated": "Zuletzt aktualisiert",
|
||||
"salesforce_on_cancel_write_to_event": "Bei stornierter Buchung in den Ereignisdatensatz schreiben, anstatt das Ereignis zu löschen",
|
||||
"salesforce_on_every_cancellation": "Bei jeder Stornierung",
|
||||
"report_issue": "Problem melden",
|
||||
"report_issue_description": "Sie können ein Ticket auf GitHub einreichen oder Ihren Plan upgraden, um Echtzeit-Support mit Entwicklerkonferenzen zu erhalten",
|
||||
"open_issue": "Problem öffnen",
|
||||
"this_is_your_current_plan": "Dies ist Ihr aktueller Plan",
|
||||
"schedule_a_time": "Einen Termin vereinbaren",
|
||||
"this_includes": "Dies beinhaltet:",
|
||||
"oauth_client_updated_successfully": "OAuth-Client erfolgreich aktualisiert",
|
||||
"oauth_client_not_found": "OAuth-Client nicht gefunden.",
|
||||
"subscribe_to_platform": "Plattform abonnieren",
|
||||
"error_accessing_webhooks": "Fehler beim Zugriff auf Webhooks.",
|
||||
"webhook_update_failed": "Aktualisierung des Webhooks fehlgeschlagen.",
|
||||
"webhook_create_failed": "Erstellung des Webhooks fehlgeschlagen.",
|
||||
"invalid_link": "Ungültiger Link",
|
||||
"currently_subscribed_to_plan": "Sie haben derzeit den {{planFirstLetter}}{{planRest}}-Plan abonniert",
|
||||
"user_team": "Benutzer/Team",
|
||||
"client_id_copied": "Client-ID kopiert!",
|
||||
"client_secret_copied": "Client-Secret kopiert!",
|
||||
"maintenance_message": "Das Cal.com-Team führt geplante Wartungsarbeiten durch. Bei Fragen wenden Sie sich bitte an den Support.",
|
||||
"your_payment_failed": "Ihre Zahlung ist fehlgeschlagen",
|
||||
"check_your_inbox": "Überprüfen Sie Ihren Posteingang",
|
||||
"account_created_premium_not_reserved": "Dein Konto wurde erstellt, aber dein Premium-Name wurde nicht reserviert.",
|
||||
"email_sent_with_activation_link": "Wir haben eine E-Mail an {{email}} mit einem Link zur Aktivierung deines Kontos gesendet.",
|
||||
"activate_account_to_purchase_username": "Sobald du dein Konto aktiviert hast, kannst du erneut versuchen, deinen Premium-Benutzernamen zu kaufen oder einen anderen auswählen.",
|
||||
"open_in_gmail": "In Gmail öffnen",
|
||||
"dont_see_email": "Keine E-Mail erhalten?",
|
||||
"resend_in_seconds": "Erneut senden in {{seconds}} Sekunden",
|
||||
"resend": "Erneut senden",
|
||||
"verification_email_sent": "Bestätigungs-E-Mail gesendet",
|
||||
"select_all_members": "Alle Mitglieder auswählen",
|
||||
"select_all_members_tooltip": "Wenn du alle Mitglieder auswählst, werden alle zukünftigen Teammitglieder hinzugefügt, sobald sie dem Team beitreten.",
|
||||
"form_settings": "Formulareinstellungen",
|
||||
"remove_whitelist_status": "Whitelist-Status entfernen",
|
||||
"whitelist_user_workflows": "Benutzer-Workflows zur Whitelist hinzufügen",
|
||||
"user_workflows_whitelisted": "Benutzer-Workflows zur Whitelist hinzugefügt",
|
||||
"user_workflows_unwhitelisted": "Benutzer-Workflows von der Whitelist entfernt",
|
||||
"date_and_time": "Datum und Uhrzeit",
|
||||
"email_reminder_upcoming_event_notice": "Dies ist eine Erinnerung an Ihre bevorstehende Veranstaltung.",
|
||||
"email_reminder_triggered_by_workflow": "Diese Erinnerung wurde durch einen Workflow in Cal ausgelöst.",
|
||||
"event_upper_case": "Ereignis",
|
||||
"scheduling_by": "Terminplanung durch",
|
||||
"experience_review_prompt": "Wie war Ihre letzte Erfahrung?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Wie zufrieden waren Sie mit Ihrer letzten Besprechung?",
|
||||
"meeting_not_joined_question": "nicht am Meeting teilgenommen?",
|
||||
"reschedule_cta_short": "Hier neu planen.",
|
||||
"hide_organizer_email": "E-Mail-Adresse des Organisators verbergen",
|
||||
"platform_customer_cant_create_organization": "Du bist bereits Teil einer Plattform-Organisation, weshalb du keine neue Organisation erstellen kannst. Jeder Benutzer kann nur einer Organisation angehören. Bitte erstelle ein neues Cal.com-Konto mit einer anderen E-Mail-Adresse und verwende dieses Konto, um das Organisations-Abonnement abzuschließen.",
|
||||
"organization_customer_cant_create_platform": "Du bist bereits Teil einer Organisation, weshalb du keine Plattform-Organisation erstellen kannst. Jeder Benutzer kann nur einer Organisation angehören. Bitte erstelle ein neues Cal.com-Konto mit einer anderen E-Mail-Adresse und verwende dieses Konto, um das Plattform-Abonnement abzuschließen.",
|
||||
"hide_organizer_email_description": "E-Mail-Adresse des Organisators im Buchungsbildschirm, in E-Mail-Benachrichtigungen und Kalenderereignissen verbergen",
|
||||
"you_and_conjunction": "Sie &",
|
||||
"email_survey_triggered_by_workflow": "Diese Umfrage wurde durch einen Workflow in Cal ausgelöst."
|
||||
"select_verified_email": "Verifizierte E-Mail-Adresse auswählen",
|
||||
"custom_reply_to_email_title": "Benutzerdefinierte 'Antwort an'-E-Mail",
|
||||
"custom_reply_to_email_description": "Verwende eine andere E-Mail-Adresse als 'Antwort an' für Bestätigungs-E-Mails anstelle der E-Mail-Adresse des Organisators",
|
||||
"email_survey_triggered_by_workflow": "Diese Umfrage wurde durch einen Workflow in Cal ausgelöst.",
|
||||
"skip_trial": "Testphase überspringen",
|
||||
"team_trials_skipped_successfully": "Team-Testphasen erfolgreich übersprungen",
|
||||
"sms_workflow_consent": "Durch die Eingabe deiner Telefonnummer stimmst du zu, SMS-Nachrichten für dieses Event zu erhalten. Es können SMS-Gebühren anfallen.",
|
||||
"routing_preview_more_info_found_insights": "Weitere Informationen finden Sie in den <0>Routing-Einblicken</0>",
|
||||
"results": "Ergebnisse",
|
||||
"view_form": "Formular anzeigen",
|
||||
"sms_opt_out_message": "Senden Sie STOP, um sich von SMS-Nachrichten abzumelden",
|
||||
"routing_form_next_in_queue": "{{count}} nächste in der Warteschlange",
|
||||
"routing_form_select_members_to_email": "E-Mail-Antworten senden an",
|
||||
"routing_incomplete_booking_tab": "Unvollständige Buchungen",
|
||||
"include_no_show_in_rr_calculation": "Nicht erschienene Buchungen in Round-Robin-Berechnungen einbeziehen",
|
||||
"matching": "Übereinstimmung",
|
||||
"event_redirect": "Event-Weiterleitung",
|
||||
"reset_form": "Formular zurücksetzen",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Fügen Sie Ihre neuen Code-Zeilen über dieser hinzu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Το πλήρες όνομά σας",
|
||||
"no_name": "Χωρίς όνομα",
|
||||
"enter_number_between_range": "Παρακαλώ εισάγετε έναν αριθμό μεταξύ 1 και {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Γρήγορα και εύκολα - δεν απαιτείται λογαριασμός. Ιδανικό για συναντήσεις μίας φοράς.",
|
||||
"email_address": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
|
||||
"enter_valid_email": "Παρακαλώ εισάγετε ένα έγκυρο email",
|
||||
"please_schedule_future_call": "Παρακαλώ προγραμματίστε μια μελλοντική κλήση εάν δεν είμαστε διαθέσιμοι σε {{seconds}} δευτερόλεπτα",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Διά ζώσης (Διεύθυνση συμμετέχοντα)",
|
||||
"somewhere_else": "Κάπου αλλού",
|
||||
"custom_attendee_location": "Προσαρμοσμένη τοποθεσία συμμετέχοντα",
|
||||
"continue_as_guest": "Συνέχεια ως επισκέπτης",
|
||||
"any_location": "Οποιαδήποτε τοποθεσία",
|
||||
"yes": "Ναί",
|
||||
"no": "Όχι",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Επιτυχής ενημέρωση ομάδας",
|
||||
"your_team_updated_successfully": "Η ομάδα σας ενημερώθηκε με επιτυχία.",
|
||||
"your_org_updated_successfully": "Ο οργανισμός σας ενημερώθηκε με επιτυχία.",
|
||||
"error_copying_to_clipboard": "Σφάλμα αντιγραφής στο πρόχειρο",
|
||||
"about": "Σχετικά",
|
||||
"team_description": "Μερικές προτάσεις σχετικά με την ομάδα σας. Αυτό θα εμφανίζεται στη σελίδα url της ομάδας σας.",
|
||||
"organization_id": "Αναγνωριστικό οργανισμού",
|
||||
"organization_id_copied": "Το αναγνωριστικό οργανισμού αντιγράφηκε.",
|
||||
"org_description": "Μερικές προτάσεις σχετικά με τον οργανισμό σας. Αυτό θα εμφανίζεται στη σελίδα url του οργανισμού σας.",
|
||||
"team_id": "Αναγνωριστικό ομάδας",
|
||||
"team_id_copied": "Το αναγνωριστικό ομάδας αντιγράφηκε.",
|
||||
"members": "Μέλη",
|
||||
"organization_members": "Μέλη οργανισμού",
|
||||
"member": "Μέλος",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Είστε βέβαιοι ότι θέλετε να αφαιρέσετε αυτό το μέλος από την ομάδα;",
|
||||
"confirm_disband_team": "Ναι, διάλυση ομάδας",
|
||||
"confirm_remove_member": "Ναι, αφαίρεση μέλους",
|
||||
"confirm_subscription_cancellation": "Ναι, ακύρωση συνδρομής",
|
||||
"cancel_subscription": "Ακύρωση συνδρομής",
|
||||
"cancel_subscription_description": "Η ακύρωση της συνδρομής σας θα απενεργοποιήσει μόνιμα το τρέχον πρόγραμμά σας. Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.",
|
||||
"remove_member": "Αφαίρεση μέλους",
|
||||
"manage_your_team": "Διαχείριση ομάδας",
|
||||
"no_teams": "Δεν έχετε καμία ομάδα ακόμη.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL της σελίδας κράτησής σας",
|
||||
"booking_cancel_redirect_uri": "URL της σελίδας όπου οι χρήστες σας μπορούν να ακυρώσουν την κράτησή τους",
|
||||
"booking_reschedule_redirect_uri": "URL της σελίδας όπου οι χρήστες σας μπορούν να επαναπρογραμματίσουν την κράτησή τους",
|
||||
"booking_conflict_error": "Αυτή η χρονοθυρίδα δεν είναι πλέον διαθέσιμη. Παρακαλώ επιστρέψτε στην προηγούμενη σελίδα και επιλέξτε άλλη ώρα.",
|
||||
"open_invitations": "Ανοιχτές προσκλήσεις",
|
||||
"new_team": "Νέα Ομάδα",
|
||||
"create_first_team_and_invite_others": "Δημιουργήστε την πρώτη σας ομάδα και προσκαλέστε άλλους χρήστες για συνεργασία.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Ο λογαριασμός σας δημιουργήθηκε χρησιμοποιώντας έναν Πάροχο Ταυτότητας.",
|
||||
"account_managed_by_identity_provider": "Ο λογαριασμός σας διαχειρίζεται από το {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Για να αλλάξετε το email σας, τον κωδικό πρόσβασης, να ενεργοποιήσετε τον έλεγχο ταυτότητας δύο παραγόντων και άλλα, παρακαλούμε επισκεφθείτε τις ρυθμίσεις του λογαριασμού σας στο {{provider}}.",
|
||||
"account_managed_by_identity_provider_error": "Ο λογαριασμός σας διαχειρίζεται από διαφορετικό πάροχο ταυτότητας. Δοκιμάστε να συνδεθείτε με {{provider}}.",
|
||||
"user_creation_error": "Σφάλμα κατά τη δημιουργία νέου χρήστη. Παρακαλώ δοκιμάστε ξανά.",
|
||||
"signin_with_google": "Σύνδεση με Google",
|
||||
"signin_with_saml": "Σύνδεση με SAML",
|
||||
"signin_with_saml_oidc": "Σύνδεση με SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Είστε έτοιμοι!",
|
||||
"install_zapier_app": "Παρακαλούμε εγκαταστήστε πρώτα την εφαρμογή Zapier από το app store.",
|
||||
"install_make_app": "Παρακαλούμε εγκαταστήστε πρώτα την εφαρμογή Make από το app store.",
|
||||
"app_installation": "Εγκατάσταση εφαρμογής",
|
||||
"app_not_installed": "Η εφαρμογή δεν έχει εγκατασταθεί",
|
||||
"visit_our_app_store": "Συγγνώμη, αυτή η εφαρμογή δεν είναι εγκατεστημένη στον λογαριασμό σας. Παρακαλούμε επισκεφθείτε το app store μας για να εξερευνήσετε και να ανακαλύψετε αυτή και άλλες εξαιρετικές εφαρμογές.",
|
||||
"connect_apple_server": "Σύνδεση με τον διακομιστή της Apple",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "όταν το συμβάν ακυρωθεί",
|
||||
"after_hosts_cal_video_no_show": "Αφού οι διοργανωτές δεν συνδέθηκαν στο cal video",
|
||||
"after_guests_cal_video_no_show": "Αφού οι καλεσμένοι δεν συνδέθηκαν στο cal video",
|
||||
"join_video_call": "Συμμετοχή στη βιντεοκλήση",
|
||||
"sign_in_to_cal_com": "Συνδεθείτε στον λογαριασμό σας στο Cal.com",
|
||||
"log_in_to_cal_com": "Σύνδεση στο Cal.com",
|
||||
"track_your_meetings": "Παρακολουθήστε τις συναντήσεις σας, λάβετε ειδοποιήσεις και διαχειριστείτε το πρόγραμμά σας πιο αποτελεσματικά.",
|
||||
"choose_how_you_d_like_to_join_call": "Επιλέξτε πώς θέλετε να συμμετάσχετε σε αυτήν την κλήση",
|
||||
"new_event_trigger": "όταν γίνει κράτηση νέου συμβάντος",
|
||||
"email_host_action": "αποστολή email στον διοργανωτή",
|
||||
"email_attendee_action": "αποστολή email στους συμμετέχοντες",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Προσαρμοσμένο",
|
||||
"reminder": "Υπενθύμιση",
|
||||
"rescheduled": "Επαναπρογραμματίστηκε",
|
||||
"rescheduled_by": "Επαναπρογραμματίστηκε από",
|
||||
"original_booking": "Αρχική κράτηση",
|
||||
"completed": "Ολοκληρώθηκε",
|
||||
"rating": "Αξιολόγηση",
|
||||
"reminder_email": "Υπενθύμιση: {{eventType}} με {{name}} στις {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "Η ροή εργασίας {{workflowName}} {{offOn}} με επιτυχία",
|
||||
"download_responses": "Λήψη απαντήσεων",
|
||||
"download_responses_description": "Κατεβάστε όλες τις απαντήσεις της φόρμας σας σε μορφή CSV.",
|
||||
"view_responses": "Προβολή απαντήσεων",
|
||||
"download": "Λήψη",
|
||||
"downloading": "Γίνεται λήψη",
|
||||
"download_recording": "Λήψη εγγραφής",
|
||||
"transcription_enabled": "Οι απομαγνητοφωνήσεις ενεργοποιήθηκαν",
|
||||
"transcription_stopped": "Οι απομαγνητοφωνήσεις σταμάτησαν",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Προσθήκη νέας φόρμας στην ομάδα σας",
|
||||
"create_your_first_route": "Δημιουργήστε την πρώτη σας διαδρομή",
|
||||
"route_to_the_right_person": "Δρομολόγηση στο κατάλληλο άτομο με βάση τις απαντήσεις της φόρμας σας",
|
||||
"form": "Φόρμα",
|
||||
"form_description": "Δημιουργήστε τη φόρμα σας για τη δρομολόγηση κρατήσεων",
|
||||
"copy_link_to_form": "Αντιγραφή συνδέσμου φόρμας",
|
||||
"theme": "Θέμα σελίδας κρατήσεων",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Λάθος κωδικός επαλήθευσης",
|
||||
"not_verified": "Δεν έχει επαληθευτεί ακόμα",
|
||||
"no_availability_in_month": "Καμία διαθεσιμότητα τον {{month}}",
|
||||
"no_availability_rolling": "Ο προγραμματισμός είναι διαθέσιμος μόνο έως και {{days}} ημέρες εκ των προτέρων. Παρακαλώ ελέγξτε ξανά σύντομα.",
|
||||
"no_availability_range": "Ο προγραμματισμός έληξε στις {{date}}. Παρακαλώ ελέγξτε ξανά σύντομα.",
|
||||
"view_previous_month": "Προβολή προηγούμενου μήνα",
|
||||
"view_next_month": "Προβολή επόμενου μήνα",
|
||||
"send_code": "Αποστολή κωδικού",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Η πληρωμή για αυτή την εκδήλωση δεν είναι πλέον δυνατή",
|
||||
"booking_with_payment_cancelled_already_paid": "Η επιστροφή χρημάτων για αυτή την κράτηση βρίσκεται σε εξέλιξη.",
|
||||
"booking_with_payment_cancelled_refunded": "Η πληρωμή για αυτή την κράτηση έχει επιστραφεί.",
|
||||
"booking_with_payment_cancelled_no_refund": "Σύμφωνα με την πολιτική επιστροφής χρημάτων της εκδήλωσης, η πληρωμή της κράτησης δεν επιστρέφεται.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Το χρονικό περιθώριο επιστροφής χρημάτων της εκδήλωσης έχει λήξει. Συνεπώς, η πληρωμή της κράτησης δεν επιστρέφεται.",
|
||||
"booking_confirmation_failed": "Η επιβεβαίωση της κράτησης απέτυχε",
|
||||
"not_enough_seats": "Δεν υπάρχουν αρκετές θέσεις",
|
||||
"form_builder_field_already_exists": "Υπάρχει ήδη ένα πεδίο με αυτό το όνομα",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Άνοιγμα διαθεσιμότητας χρηστών",
|
||||
"organization_no_slots_notification_switch_title": "Λάβετε ειδοποιήσεις όταν η ομάδα σας δεν έχει διαθεσιμότητα",
|
||||
"organization_no_slots_notification_switch_description": "Οι διαχειριστές θα λαμβάνουν ειδοποιήσεις μέσω email όταν ένας χρήστης προσπαθεί να κλείσει ραντεβού με μέλος της ομάδας και αντιμετωπίζει 'Καμία διαθεσιμότητα'. Στέλνουμε αυτό το email μετά από δύο περιστατικά και σας υπενθυμίζουμε κάθε 7 ημέρες ανά χρήστη.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Απενεργοποίηση ειδοποιήσεων SMS για τύπους εκδηλώσεων μόνο με τηλέφωνο",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Απενεργοποίηση αυτόματων ειδοποιήσεων SMS για τύπους εκδηλώσεων που απαιτούν μόνο αριθμό τηλεφώνου (attendeePhoneNumber) ως υποχρεωτική ερώτηση με το email ως προαιρετικό ή μη απαιτούμενο",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} added you to the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} invited you to join the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} added you to the team {{team}} of organization {{parentTeamName}} on {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Ο σύνδεσμός σας έχει αλλάξει από {{a0}} σε {{a1}} αλλά μην ανησυχείτε, όλοι οι προηγούμενοι σύνδεσμοι εξακολουθούν να λειτουργούν και να ανακατευθύνουν κατάλληλα. <br /><br />Παρακαλώ σημειώστε: Όλοι οι προσωπικοί τύποι εκδηλώσεών σας έχουν μεταφερθεί στον οργανισμό <strong>{{teamName}}</strong>, που μπορεί επίσης να περιλαμβάνει πιθανό προσωπικό σύνδεσμο.<br /><br />Παρακαλώ συνδεθείτε και βεβαιωθείτε ότι δεν έχετε ιδιωτικές εκδηλώσεις στον νέο οργανωτικό σας λογαριασμό.<br /><br />Για προσωπικές εκδηλώσεις συνιστούμε τη δημιουργία νέου λογαριασμού με προσωπική διεύθυνση email.<br /><br />Απολαύστε τον νέο καθαρό σύνδεσμό σας: {{a2}}",
|
||||
"email_organization_created|subject": "Ο οργανισμός σας έχει δημιουργηθεί",
|
||||
"your_current_plan": "Το τρέχον πλάνο σας",
|
||||
"organization_price_per_user_month": "$37 ανά χρήστη ανά μήνα (ελάχιστο 30 θέσεις)",
|
||||
"organization_price_per_user_month": "$37 ανά χρήστη ανά μήνα",
|
||||
"privacy_organization_description": "Διαχειριστείτε τις ρυθμίσεις απορρήτου για τον οργανισμό σας",
|
||||
"privacy": "Απόρρητο",
|
||||
"team_will_be_under_org": "Οι νέες ομάδες θα υπάγονται στον οργανισμό σας",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Προχωρώντας, συμφωνείτε με τους",
|
||||
"terms": "Όρους",
|
||||
"always_show_x_days": "Πάντα {{x}} διαθέσιμες ημέρες",
|
||||
"team_subscription_cancelled_successfully": "Η συνδρομή ομάδας ακυρώθηκε με επιτυχία",
|
||||
"team_subscription_cancellation_error": "Σφάλμα κατά την ακύρωση της συνδρομής ομάδας",
|
||||
"unable_to_subscribe_to_the_platform": "Παρουσιάστηκε σφάλμα κατά την εγγραφή στο πρόγραμμα της πλατφόρμας, παρακαλώ δοκιμάστε ξανά αργότερα",
|
||||
"updating_oauth_client_error": "Παρουσιάστηκε σφάλμα κατά την ενημέρωση του OAuth client, παρακαλώ δοκιμάστε ξανά αργότερα",
|
||||
"creating_oauth_client_error": "Παρουσιάστηκε σφάλμα κατά τη δημιουργία του OAuth client, παρακαλώ δοκιμάστε ξανά αργότερα",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Παράλειψη δημιουργίας εγγραφής {{entry}} εάν δεν υπάρχει στο Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Εάν η επαφή δεν υπάρχει υπό κάποιο λογαριασμό, δημιούργησε νέο lead από τον συμμετέχοντα",
|
||||
"salesforce_create_new_contact_under_account": "Δημιούργησε νέα επαφή υπό λογαριασμό με βάση το domain email του συμμετέχοντα και τις υπάρχουσες επαφές",
|
||||
"salesforce_change_record_owner_on_booking": "Αλλαγή ιδιοκτήτη εγγραφής κατά την κράτηση",
|
||||
"mass_assign_attributes": "Μαζική εκχώρηση χαρακτηριστικών",
|
||||
"reroute_preview_custom_message": "Αυτό έχει ως αποτέλεσμα την εμφάνιση προσαρμοσμένου μηνύματος. Δοκιμάστε να αλλάξετε την απάντηση για να δρομολογηθείτε σε ένα συμβάν",
|
||||
"reroute_preview_external_redirect": "Αυτό έχει ως αποτέλεσμα την ανακατεύθυνση στο {{externalUrl}}. Δοκιμάστε να αλλάξετε την απάντηση για να δρομολογηθείτε σε ένα συμβάν",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Δρομολογήθηκαν ανά περίοδο",
|
||||
"per_day": "Ανά ημέρα",
|
||||
"per_week": "Ανά εβδομάδα",
|
||||
"per_month": "Ανά μήνα",
|
||||
"per_month": "ανά μήνα",
|
||||
"routing_form_insights_assignment_reason": "Αιτία ανάθεσης",
|
||||
"access_denied": "Δεν επιτρέπεται η πρόσβαση",
|
||||
"salesforce_route_to_owner": "Ο κάτοχος της επαφής θα είναι ο round robin διοργανωτής εάν είναι διαθέσιμος",
|
||||
"salesforce_add_attendees_as": "Προσθήκη νέων συμμετεχόντων ως",
|
||||
"salesforce_do_not_route_to_owner": "Ο κάτοχος της επαφής δεν θα είναι υποχρεωτικός (μπορεί ακόμα να είναι διοργανωτής εάν ταιριάζει με τα χαρακτηριστικά και τα κριτήρια round robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Δρομολόγηση σε χρήστη που ταιριάζει με ένα πεδίο αναζήτησης σε λογαριασμό",
|
||||
"salesforce_option": "Επιλογή Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Έλλειμμα",
|
||||
"routing_form": "Φόρμα δρομολόγησης",
|
||||
"go_back_and_save": "Επιστροφή και αποθήκευση",
|
||||
"save_changes": "Αποθήκευση αλλαγών",
|
||||
"leave_without_saving": "Έξοδος χωρίς αποθήκευση",
|
||||
"leave_without_saving_description": "Είστε βέβαιοι ότι θέλετε να αποχωρήσετε χωρίς να αποθηκεύσετε τις αλλαγές στη φόρμα δρομολόγησης;",
|
||||
"something_unexpected_occurred": "Συνέβη κάτι απρόσμενο",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Εξουσιοδότηση",
|
||||
"next": "Επόμενο",
|
||||
"hide": "Απόκρυψη",
|
||||
"show": "Εμφάνιση",
|
||||
"utm_params": "Παράμετροι UTM",
|
||||
"no_utm_params": "Δεν υπάρχουν διαθέσιμες παράμετροι UTM.",
|
||||
"asc": "Αύξουσα",
|
||||
"desc": "Φθίνουσα",
|
||||
"verify_email_change": "Επαλήθευση αλλαγής email",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Πρέπει να έχετε τον ελάχιστο αριθμό δημοσιευμένων ομάδων",
|
||||
"you_are_part_of_this_organization_already": "Είστε ήδη μέλος αυτού του οργανισμού",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Είστε μέλος άλλου οργανισμού, δεν μπορείτε να δημιουργήσετε νέο οργανισμό",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Είστε μέλος άλλου οργανισμού πλατφόρμας, δεν μπορείτε να δημιουργήσετε νέο οργανισμό",
|
||||
"organization_payment_success": "Επιτυχής πληρωμή οργανισμού",
|
||||
"organization_payment_success_description": "Ο οργανισμός σας δημιουργήθηκε με επιτυχία",
|
||||
"this_may_take_a_few_seconds": "Αυτό μπορεί να διαρκέσει μερικά δευτερόλεπτα...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Η εισαγωγή οργανισμού έχει ήδη ολοκληρωθεί",
|
||||
"organization_onboarding_already_exists": "Η εισαγωγή οργανισμού υπάρχει ήδη",
|
||||
"organization_onboarding_not_found": "Η εισαγωγή οργανισμού δεν βρέθηκε",
|
||||
"payment_successful": "Επιτυχής πληρωμή",
|
||||
"payment_successful": "Επιτυχής πληρωμή!",
|
||||
"handover_onboarding_page_title": "Παράδοση εισαγωγής",
|
||||
"handover_onboarding_page_description": "Παράδοση εισαγωγής στον χρήστη",
|
||||
"organization_already_exists_with_this_slug": "Υπάρχει ήδη οργανισμός με αυτό το slug",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Σύνδεσμος",
|
||||
"rows_per_page": "γραμμές ανά σελίδα",
|
||||
"pagination_status": "{{currentRange}} από {{totalItems}}",
|
||||
"tip_username_plus": "Συμβουλή: Μπορείτε να προσθέσετε ένα '+' μεταξύ των ονομάτων χρήστη: cal.com/anna+brian για να δημιουργήσετε μια δυναμική ομαδική συνάντηση",
|
||||
"tip_username_plus": "Συμβουλή: Μπορείτε να προσθέσετε ένα '+' μεταξύ των ονομάτων χρηστών: cal.com/anna+brian για να δημιουργήσετε μια δυναμική ομαδική συνάντηση",
|
||||
"user_has_no_team_yet": "Δεν έχετε ακόμη ομάδα",
|
||||
"no_team_members": "Δεν έχετε ακόμη μέλη ομάδας",
|
||||
"recurring_event_doesnt_support_seats": "Η επαναλαμβανόμενη εκδήλωση δεν υποστηρίζει τη λειτουργία θέσεων. Κάντε την μη επαναλαμβανόμενη για να ενεργοποιήσετε τις θέσεις.",
|
||||
"seats_doesnt_support_recurring": "Η λειτουργία θέσεων δεν υποστηρίζει επαναλαμβανόμενη εκδήλωση. Απενεργοποιήστε τη λειτουργία θέσεων για να την κάνετε επαναλαμβανόμενη.",
|
||||
"recurring_event_seats_error": "Η επαναλαμβανόμενη εκδήλωση δεν υποστηρίζει τη λειτουργία θέσεων. Απενεργοποιήστε τη λειτουργία θέσεων ή κάντε την εκδήλωση μη επαναλαμβανόμενη.",
|
||||
"segment": "Τμήμα",
|
||||
"rename": "Μετονομασία",
|
||||
"rename_segment": "Μετονομασία τμήματος",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Περισσότερες ακυρωμένες κρατήσεις",
|
||||
"name_or_email": "Όνομα ή Email",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Αν δεν βρεθεί επαφή, επιστροφή στον ιδιοκτήτη του lead εάν υπάρχει",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Προσθέστε τις νέες συμβολοσειρές σας πάνω από εδώ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Ημερομηνία & Ώρα",
|
||||
"email_reminder_upcoming_event_notice" : "Αυτή είναι μια υπενθύμιση για την επερχόμενη εκδήλωσή σας.",
|
||||
"email_reminder_triggered_by_workflow" : "Αυτή η υπενθύμιση ενεργοποιήθηκε από μια ροή εργασίας στο Cal.",
|
||||
"enable_delegation_credential": "Ενεργοποίηση διαπιστευτηρίου εξουσιοδότησης",
|
||||
"enable_delegation_credential_description": "Παραχωρήστε στο Cal.com αυτόματη πρόσβαση στα ημερολόγια όλων των μελών του οργανισμού ενεργοποιώντας το διαπιστευτήριο εξουσιοδότησης.",
|
||||
"disable_delegation_credential": "Απενεργοποίηση διαπιστευτηρίου εξουσιοδότησης",
|
||||
"disable_delegation_credential_description": "Μόλις απενεργοποιηθεί το διαπιστευτήριο εξουσιοδότησης, τα μέλη του οργανισμού που δεν έχουν συνδέσει τα ημερολόγιά τους θα πρέπει να το κάνουν χειροκίνητα.",
|
||||
"last_active": "Τελευταία ενεργός",
|
||||
"member_since": "Μέλος από",
|
||||
"last_updated": "Τελευταία ενημέρωση",
|
||||
"salesforce_on_cancel_write_to_event": "Σε ακύρωση κράτησης, εγγραφή στο αρχείο συμβάντος αντί για διαγραφή συμβάντος",
|
||||
"salesforce_on_every_cancellation": "Σε κάθε ακύρωση",
|
||||
"report_issue": "Αναφορά προβλήματος",
|
||||
"report_issue_description": "Μπορείτε να υποβάλετε ένα αίτημα στο GitHub ή να αναβαθμίσετε το πρόγραμμά σας για να λάβετε υποστήριξη σε πραγματικό χρόνο με συνεδρίες προγραμματιστών",
|
||||
"open_issue": "Άνοιγμα ζητήματος",
|
||||
"this_is_your_current_plan": "Αυτό είναι το τρέχον πρόγραμμά σας",
|
||||
"schedule_a_time": "Προγραμματίστε μια ώρα",
|
||||
"this_includes": "Αυτό περιλαμβάνει:",
|
||||
"oauth_client_updated_successfully": "Ο πελάτης OAuth ενημερώθηκε με επιτυχία",
|
||||
"oauth_client_not_found": "Ο πελάτης OAuth δεν βρέθηκε.",
|
||||
"subscribe_to_platform": "Εγγραφή στην πλατφόρμα",
|
||||
"error_accessing_webhooks": "Σφάλμα κατά την προσπάθεια πρόσβασης στα webhooks.",
|
||||
"webhook_update_failed": "Αποτυχία ενημέρωσης του webhook.",
|
||||
"webhook_create_failed": "Αποτυχία δημιουργίας του webhook.",
|
||||
"invalid_link": "Μη έγκυρος σύνδεσμος",
|
||||
"currently_subscribed_to_plan": "Είστε συνδρομητής στο πρόγραμμα {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Χρήστης/Ομάδα",
|
||||
"client_id_copied": "Το αναγνωριστικό πελάτη αντιγράφηκε!",
|
||||
"client_secret_copied": "Το μυστικό πελάτη αντιγράφηκε!",
|
||||
"maintenance_message": "Η ομάδα του Cal.com πραγματοποιεί προγραμματισμένη συντήρηση. Εάν έχετε ερωτήσεις, επικοινωνήστε με την υποστήριξη.",
|
||||
"your_payment_failed": "Η πληρωμή σας απέτυχε",
|
||||
"check_your_inbox": "Ελέγξτε τα εισερχόμενά σας",
|
||||
"account_created_premium_not_reserved": "Ο λογαριασμός σας έχει δημιουργηθεί, αλλά το premium όνομα χρήστη σας δεν έχει δεσμευτεί.",
|
||||
"email_sent_with_activation_link": "Έχουμε στείλει ένα email στο {{email}} με έναν σύνδεσμο για την ενεργοποίηση του λογαριασμού σας.",
|
||||
"activate_account_to_purchase_username": "Μόλις ενεργοποιήσετε τον λογαριασμό σας, θα μπορείτε να προσπαθήσετε να αγοράσετε ξανά το premium όνομα χρήστη σας ή να επιλέξετε ένα διαφορετικό.",
|
||||
"open_in_gmail": "Άνοιγμα στο Gmail",
|
||||
"dont_see_email": "Δεν βλέπετε κάποιο email;",
|
||||
"resend_in_seconds": "Επαναποστολή σε {{seconds}} δευτερόλεπτα",
|
||||
"resend": "Επαναποστολή",
|
||||
"verification_email_sent": "Το email επαλήθευσης εστάλη",
|
||||
"select_all_members": "Επιλογή όλων των μελών",
|
||||
"select_all_members_tooltip": "Η επιλογή όλων των μελών θα προσθέσει όλα τα μελλοντικά μέλη της ομάδας όταν προστεθούν στην ομάδα.",
|
||||
"form_settings": "Ρυθμίσεις φόρμας",
|
||||
"remove_whitelist_status": "Αφαίρεση κατάστασης λευκής λίστας",
|
||||
"whitelist_user_workflows": "Προσθήκη ροών εργασίας χρήστη στη λευκή λίστα",
|
||||
"user_workflows_whitelisted": "Οι ροές εργασίας χρήστη προστέθηκαν στη λευκή λίστα",
|
||||
"user_workflows_unwhitelisted": "Οι ροές εργασίας χρήστη αφαιρέθηκαν από τη λευκή λίστα",
|
||||
"date_and_time": "Ημερομηνία & Ώρα",
|
||||
"email_reminder_upcoming_event_notice": "Αυτή είναι μια υπενθύμιση για την επερχόμενη εκδήλωσή σας.",
|
||||
"email_reminder_triggered_by_workflow": "Αυτή η υπενθύμιση ενεργοποιήθηκε από μια ροή εργασίας στο Cal.",
|
||||
"event_upper_case": "Γεγονός",
|
||||
"scheduling_by": "Προγραμματισμός από",
|
||||
"experience_review_prompt": "Πώς ήταν η πρόσφατη εμπειρία σας;",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Πόσο ικανοποιημένοι ήσασταν με την τελευταία σας συνάντηση;",
|
||||
"meeting_not_joined_question": "δεν συμμετείχατε στη συνάντηση;",
|
||||
"reschedule_cta_short": "Επαναπρογραμματίστε εδώ.",
|
||||
"hide_organizer_email": "Απόκρυψη email διοργανωτή",
|
||||
"platform_customer_cant_create_organization": "Είστε ήδη μέλος ενός οργανισμού πλατφόρμας, γι' αυτό δεν μπορείτε να δημιουργήσετε νέο οργανισμό. Κάθε χρήστης μπορεί να ανήκει μόνο σε έναν οργανισμό. Παρακαλούμε, δημιουργήστε έναν νέο λογαριασμό cal.com με διαφορετικό email και χρησιμοποιήστε αυτόν τον λογαριασμό για να εγγραφείτε στο πρόγραμμα οργανισμών.",
|
||||
"organization_customer_cant_create_platform": "Είστε ήδη μέλος ενός οργανισμού, γι' αυτό δεν μπορείτε να δημιουργήσετε οργανισμό πλατφόρμας. Κάθε χρήστης μπορεί να ανήκει μόνο σε έναν οργανισμό. Παρακαλούμε, δημιουργήστε έναν νέο λογαριασμό cal.com με διαφορετικό email και χρησιμοποιήστε αυτόν τον λογαριασμό για να εγγραφείτε στο πρόγραμμα πλατφόρμας.",
|
||||
"hide_organizer_email_description": "Απόκρυψη της διεύθυνσης email του διοργανωτή από την οθόνη κράτησης, τις ειδοποιήσεις email και τα συμβάντα ημερολογίου",
|
||||
"you_and_conjunction": "Εσείς &",
|
||||
"email_survey_triggered_by_workflow": "Αυτή η έρευνα ενεργοποιήθηκε από μια ροή εργασίας στο Cal."
|
||||
"select_verified_email": "Επιλογή επαληθευμένου email",
|
||||
"custom_reply_to_email_title": "Προσαρμοσμένο email 'Απάντησης-Προς'",
|
||||
"custom_reply_to_email_description": "Χρησιμοποιήστε διαφορετική διεύθυνση email ως replyTo για τα email επιβεβαίωσης αντί για το email του διοργανωτή",
|
||||
"email_survey_triggered_by_workflow": "Αυτή η έρευνα ενεργοποιήθηκε από μια ροή εργασίας στο Cal.",
|
||||
"skip_trial": "Παράλειψη δοκιμαστικής περιόδου",
|
||||
"team_trials_skipped_successfully": "Οι δοκιμαστικές περίοδοι ομάδας παραλείφθηκαν με επιτυχία",
|
||||
"sms_workflow_consent": "Εισάγοντας τον αριθμό τηλεφώνου σας, συναινείτε να λαμβάνετε μηνύματα SMS για αυτό το συμβάν. Ενδέχεται να ισχύουν χρεώσεις SMS.",
|
||||
"routing_preview_more_info_found_insights": "Περισσότερες πληροφορίες μπορείτε να βρείτε στα <0>Στατιστικά Δρομολόγησης</0>",
|
||||
"results": "Αποτελέσματα",
|
||||
"view_form": "Προβολή φόρμας",
|
||||
"sms_opt_out_message": "Στείλτε STOP για να διακόψετε τα μηνύματα SMS",
|
||||
"routing_form_next_in_queue": "{{count}} επόμενα στην ουρά",
|
||||
"routing_form_select_members_to_email": "Αποστολή απαντήσεων email σε",
|
||||
"routing_incomplete_booking_tab": "Ημιτελείς Κρατήσεις",
|
||||
"include_no_show_in_rr_calculation": "Συμπερίληψη κρατήσεων χωρίς εμφάνιση στους υπολογισμούς round robin",
|
||||
"matching": "Αντιστοίχιση",
|
||||
"event_redirect": "Ανακατεύθυνση εκδήλωσης",
|
||||
"reset_form": "Επαναφορά φόρμας",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Προσθέστε τις νέες συμβολοσειρές σας πάνω από εδώ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -3021,6 +3021,12 @@
|
||||
"asc": "Asc",
|
||||
"desc": "Desc",
|
||||
"verify_email_change": "Verify email change",
|
||||
"buy_credits": "Buy Credits",
|
||||
"credits": "Credits",
|
||||
"view_and_manage_credits": "View and manage credits",
|
||||
"view_and_manage_credits_description": "View and manage credits for sending SMS messages. One credit is worth 1¢ (USD)",
|
||||
"buy_additional_credits": "Buy additional credits ($0.01 per credit)",
|
||||
"overview": "Overview",
|
||||
"organization_slug_taken": "Organization slug is already taken",
|
||||
"you_cannot_create_an_organization_as_you_are_already_part_of_an_organization": "You cannot create an organization as you are already a part of an organization",
|
||||
"you_need_to_complete_user_onboarding_before_creating_an_organization": "You need to complete user onboarding before creating an organization",
|
||||
@@ -3114,6 +3120,8 @@
|
||||
"most_cancelled_bookings": "Most Cancelled Bookings",
|
||||
"name_or_email": "Name or Email",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "If no contact is found, fallback to lead owner if it exists",
|
||||
"credit_purchase_failed": "Credit purchase failed. Please try again or contact support.",
|
||||
"minimum_of_credits_required": "Minimum of 50 credits required",
|
||||
"enable_delegation_credential": "Enable Delegation Credential",
|
||||
"enable_delegation_credential_description": "Grant Cal.com automatic access to the calendars of all organization members by enabling delegation credential.",
|
||||
"disable_delegation_credential": "Disable Delegation Credential",
|
||||
@@ -3141,7 +3149,6 @@
|
||||
"user_team": "User/Team",
|
||||
"client_id_copied": "Client ID copied!",
|
||||
"client_secret_copied": "Client secret copied!",
|
||||
"down_for_maintenance": "Down for maintenance",
|
||||
"maintenance_message": "The Cal.com team are performing scheduled maintenance. If you have any questions, please contact support.",
|
||||
"your_payment_failed": "Your payment failed",
|
||||
"payment_successful": "Payment successful!",
|
||||
@@ -3187,11 +3194,29 @@
|
||||
"results": "Results",
|
||||
"view_form": "View Form",
|
||||
"sms_opt_out_message": "Text STOP to opt-out of SMS messages",
|
||||
"team_credits_low_warning": "Your team {{teamName}} is running low on credits",
|
||||
"user_credits_low_warning": "You are running low on credits",
|
||||
"action_required_out_of_credits": "[Action Required] Your team {{teamName}} has run out of credits",
|
||||
"action_required_user_out_of_credits": "[Action Required] You have run out of credits",
|
||||
"low_credits_warning_message": "Your Cal.com team {{teamName}} is running low on credits. To avoid any disruption in service, please purchase additional credits. If your balance runs out, SMS messages will stop sending and will be sent as emails instead.",
|
||||
"low_credits_warning_message_user": "Your Cal.com account is running low on credits. To avoid any disruption in service, please purchase additional credits. If your balance runs out, SMS messages will stop sending and will be sent as emails instead.",
|
||||
"credit_limit_reached_message": "Your Cal.com team {{teamName}} has run out of credits. As a result, SMS messages are now being sent via email instead. To resume sending SMS, please purchase additional credits.",
|
||||
"credit_limit_reached_message_user": "Your Cal.com account has run out of credits. As a result, SMS messages are now being sent via email instead. To resume sending SMS, please purchase additional credits.",
|
||||
"current_credit_balance": "Current balance: {{balance}} credits",
|
||||
"notification_about_your_booking": "Notification about your booking",
|
||||
"monthly_credits": "Monthly credits",
|
||||
"total_credits": "Total credits: {{totalCredits}}",
|
||||
"remaining_credits": "Remaining credits: {{remainingCredits}}",
|
||||
"additional_credits": "Additional credits",
|
||||
"routing_form_next_in_queue": "{{count}} next in queue",
|
||||
"routing_form_select_members_to_email": "Send email responses to",
|
||||
"routing_incomplete_booking_tab": "Incomplete Bookings",
|
||||
"include_no_show_in_rr_calculation": "Include no show bookings in round robin calculations",
|
||||
"matching": "Matching",
|
||||
"event_redirect": "Event Redirect",
|
||||
"reset_form": "Reset Form",
|
||||
"requires_credits": "Requires credits",
|
||||
"requires_credits_tooltip": "You need enough credits in your account to use this feature",
|
||||
"available_credits": "Available credits",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Tu nombre completo",
|
||||
"no_name": "Sin nombre",
|
||||
"enter_number_between_range": "Por favor, ingresa un número entre 1 y {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Rápido y fácil - no se requiere cuenta. Perfecto para reuniones únicas.",
|
||||
"email_address": "Correo electrónico",
|
||||
"enter_valid_email": "Por favor, ingresa un correo electrónico válido",
|
||||
"please_schedule_future_call": "Por favor, programa una llamada futura si no estamos disponibles en {{seconds}} segundos",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "En persona (Dirección del asistente)",
|
||||
"somewhere_else": "En otro lugar",
|
||||
"custom_attendee_location": "Ubicación personalizada del asistente",
|
||||
"continue_as_guest": "Continuar como invitado",
|
||||
"any_location": "Cualquier ubicación",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Equipo actualizado con éxito",
|
||||
"your_team_updated_successfully": "Tu equipo ha sido actualizado con éxito.",
|
||||
"your_org_updated_successfully": "Tu organización ha sido actualizada con éxito.",
|
||||
"error_copying_to_clipboard": "Error al copiar al portapapeles",
|
||||
"about": "Acerca de",
|
||||
"team_description": "Unas pocas oraciones sobre tu equipo. Esto aparecerá en la página de la URL de tu equipo.",
|
||||
"organization_id": "ID de la organización",
|
||||
"organization_id_copied": "ID de la organización copiado.",
|
||||
"org_description": "Unas pocas oraciones sobre tu organización. Esto aparecerá en la página de la URL de tu organización.",
|
||||
"team_id": "ID del equipo",
|
||||
"team_id_copied": "ID del equipo copiado.",
|
||||
"members": "Miembros",
|
||||
"organization_members": "Miembros de la organización",
|
||||
"member": "Miembro",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "¿Estás seguro de que quieres eliminar a este miembro del equipo?",
|
||||
"confirm_disband_team": "Sí, disolver equipo",
|
||||
"confirm_remove_member": "Sí, eliminar miembro",
|
||||
"confirm_subscription_cancellation": "Sí, cancelar suscripción",
|
||||
"cancel_subscription": "Cancelar suscripción",
|
||||
"cancel_subscription_description": "Al cancelar tu suscripción desactivarás permanentemente tu plan actual. Esta acción no se puede deshacer.",
|
||||
"remove_member": "Eliminar miembro",
|
||||
"manage_your_team": "Gestiona tu equipo",
|
||||
"no_teams": "Aún no tienes equipos.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL de tu página de reservas",
|
||||
"booking_cancel_redirect_uri": "URL de la página donde tus usuarios pueden cancelar su reserva",
|
||||
"booking_reschedule_redirect_uri": "URL de la página donde tus usuarios pueden reprogramar su reserva",
|
||||
"booking_conflict_error": "Este horario ya no está disponible. Por favor regresa a la página anterior y selecciona otro horario.",
|
||||
"open_invitations": "Invitaciones Abiertas",
|
||||
"new_team": "Nuevo Equipo",
|
||||
"create_first_team_and_invite_others": "Crea tu primer equipo e invita a otros usuarios a trabajar juntos.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Tu cuenta fue creada usando un Proveedor de Identidad.",
|
||||
"account_managed_by_identity_provider": "Tu cuenta es gestionada por {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Para cambiar tu correo electrónico, contraseña, habilitar la autenticación de dos factores y más, por favor visita la configuración de tu cuenta de {{provider}}.",
|
||||
"account_managed_by_identity_provider_error": "Tu cuenta es administrada por un proveedor de identidad diferente. Intenta iniciar sesión con {{provider}}.",
|
||||
"user_creation_error": "Error al crear un nuevo usuario. Por favor intenta de nuevo.",
|
||||
"signin_with_google": "Iniciar sesión con Google",
|
||||
"signin_with_saml": "Iniciar sesión con SAML",
|
||||
"signin_with_saml_oidc": "Iniciar sesión con SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "¡Todo listo!",
|
||||
"install_zapier_app": "Por favor, primero instala la aplicación de Zapier en la tienda de aplicaciones.",
|
||||
"install_make_app": "Por favor, primero instala la aplicación de Make en la tienda de aplicaciones.",
|
||||
"app_installation": "Instalación de la aplicación",
|
||||
"app_not_installed": "Aplicación no instalada",
|
||||
"visit_our_app_store": "Lo sentimos, esta aplicación no está instalada en tu cuenta. Por favor, visita nuestra tienda de aplicaciones para explorar y descubrir esta y otras excelentes aplicaciones.",
|
||||
"connect_apple_server": "Conectar al servidor de Apple",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "cuando el evento está cancelado",
|
||||
"after_hosts_cal_video_no_show": "Después de que los anfitriones no se unieron a la videollamada",
|
||||
"after_guests_cal_video_no_show": "Después de que los invitados no se unieron a la videollamada",
|
||||
"join_video_call": "Unirse a la videollamada",
|
||||
"sign_in_to_cal_com": "Inicia sesión en tu cuenta de Cal.com",
|
||||
"log_in_to_cal_com": "Iniciar sesión en Cal.com",
|
||||
"track_your_meetings": "Rastrea tus reuniones, recibe notificaciones y administra tu agenda de manera más efectiva.",
|
||||
"choose_how_you_d_like_to_join_call": "Elige cómo te gustaría unirte a esta llamada",
|
||||
"new_event_trigger": "cuando se reserva un nuevo evento",
|
||||
"email_host_action": "enviar correo electrónico al anfitrión",
|
||||
"email_attendee_action": "enviar correo electrónico a los asistentes",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Personalizado",
|
||||
"reminder": "Recordatorio",
|
||||
"rescheduled": "Reprogramado",
|
||||
"rescheduled_by": "Reprogramado por",
|
||||
"original_booking": "Reserva original",
|
||||
"completed": "Completado",
|
||||
"rating": "Calificación",
|
||||
"reminder_email": "Recordatorio: {{eventType}} con {{name}} a las {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "El flujo de trabajo {{workflowName}} se ha {{offOn}} con éxito",
|
||||
"download_responses": "Descargar respuestas",
|
||||
"download_responses_description": "Descarga todas las respuestas a tu formulario en formato CSV.",
|
||||
"view_responses": "Ver respuestas",
|
||||
"download": "Descargar",
|
||||
"downloading": "Descargando",
|
||||
"download_recording": "Descargar grabación",
|
||||
"transcription_enabled": "Las transcripciones están habilitadas ahora",
|
||||
"transcription_stopped": "Las transcripciones se han detenido ahora",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Agregar nuevo formulario a su equipo",
|
||||
"create_your_first_route": "Cree su primera ruta",
|
||||
"route_to_the_right_person": "Dirija a la persona correcta según las respuestas de su formulario",
|
||||
"form": "Formulario",
|
||||
"form_description": "Cree su formulario para dirigir a un reservador",
|
||||
"copy_link_to_form": "Copiar enlace al formulario",
|
||||
"theme": "Tema de la página de reservas",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Código de verificación incorrecto",
|
||||
"not_verified": "Aún no verificado",
|
||||
"no_availability_in_month": "No hay disponibilidad en {{month}}",
|
||||
"no_availability_rolling": "La programación solo está disponible hasta {{days}} días por adelantado. Por favor revisa nuevamente pronto.",
|
||||
"no_availability_range": "La programación terminó el {{date}}. Por favor, revisa de nuevo pronto.",
|
||||
"view_previous_month": "Ver mes anterior",
|
||||
"view_next_month": "Ver el próximo mes",
|
||||
"send_code": "Enviar código",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Pagar por este evento ya no es posible",
|
||||
"booking_with_payment_cancelled_already_paid": "Un reembolso para este pago de reserva está en camino.",
|
||||
"booking_with_payment_cancelled_refunded": "Este pago de reserva ha sido reembolsado.",
|
||||
"booking_with_payment_cancelled_no_refund": "Según la política de reembolso del evento, el pago de la reserva no es reembolsable.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "El período de reembolso del evento ha expirado. Por lo tanto, el pago de la reserva no es reembolsable.",
|
||||
"booking_confirmation_failed": "La confirmación de la reserva falló",
|
||||
"not_enough_seats": "No hay suficientes asientos",
|
||||
"form_builder_field_already_exists": "Ya existe un campo con este nombre",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Abrir disponibilidad de usuarios",
|
||||
"organization_no_slots_notification_switch_title": "Recibir notificaciones cuando tu equipo no tenga disponibilidad",
|
||||
"organization_no_slots_notification_switch_description": "Los administradores recibirán notificaciones por correo electrónico cuando un usuario intente reservar con un miembro del equipo y se enfrente a 'Sin disponibilidad'. Enviamos este correo después de dos ocurrencias y te recordamos cada 7 días por usuario.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Desactivar notificaciones SMS para tipos de eventos solo con teléfono",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Desactivar notificaciones SMS automáticas para tipos de eventos que solo tienen número de teléfono (attendeePhoneNumber) como pregunta obligatoria con correo electrónico opcional o no requerido",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} te agregó a la organización {{team}} en {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} te invitó a unirte a la organización {{team}} en {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} te agregó al equipo {{team}} de la organización {{parentTeamName}} en {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Tu enlace ha cambiado de {{a0}} a {{a1}}, pero no te preocupes, todos los enlaces anteriores siguen funcionando y redireccionando adecuadamente. <br /><br />Ten en cuenta: Todos tus tipos de eventos personales se han movido a la organización <strong>{{teamName}}</strong>, lo que también puede incluir un posible enlace personal.<br /><br />Por favor, inicia sesión y asegúrate de no tener eventos privados en tu nueva cuenta organizacional.<br /><br />Para eventos personales, recomendamos crear una nueva cuenta con una dirección de correo electrónico personal.<br /><br />Disfruta de tu nuevo enlace limpio: {{a2}}",
|
||||
"email_organization_created|subject": "Tu organización ha sido creada",
|
||||
"your_current_plan": "Tu plan actual",
|
||||
"organization_price_per_user_month": "$37 por usuario al mes (mínimo 30 asientos)",
|
||||
"organization_price_per_user_month": "$37 por usuario al mes",
|
||||
"privacy_organization_description": "Gestiona la configuración de privacidad de tu organización",
|
||||
"privacy": "Privacidad",
|
||||
"team_will_be_under_org": "Los nuevos equipos estarán bajo tu organización",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Al continuar, aceptas nuestros",
|
||||
"terms": "Términos",
|
||||
"always_show_x_days": "Siempre {{x}} días disponibles",
|
||||
"team_subscription_cancelled_successfully": "Suscripción del equipo cancelada con éxito",
|
||||
"team_subscription_cancellation_error": "Error al cancelar la suscripción del equipo",
|
||||
"unable_to_subscribe_to_the_platform": "Ocurrió un error al intentar suscribirse al plan de la plataforma, por favor intenta de nuevo más tarde",
|
||||
"updating_oauth_client_error": "Ocurrió un error al actualizar el cliente OAuth, por favor intenta de nuevo más tarde",
|
||||
"creating_oauth_client_error": "Ocurrió un error al crear el cliente OAuth, por favor intenta de nuevo más tarde",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Omitir la creación del registro de {{entry}} si no existe en Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Si el contacto no existe bajo una cuenta, crear un nuevo cliente potencial a partir del asistente",
|
||||
"salesforce_create_new_contact_under_account": "Crear un nuevo contacto bajo una cuenta basado en el dominio de correo electrónico del asistente y los contactos existentes",
|
||||
"salesforce_change_record_owner_on_booking": "Cambiar propietario del registro en la reserva",
|
||||
"mass_assign_attributes": "Asignar atributos en masa",
|
||||
"reroute_preview_custom_message": "Resulta en mostrar un mensaje personalizado. Intenta cambiar la respuesta para redirigir a un evento",
|
||||
"reroute_preview_external_redirect": "Resulta en redirigir a {{externalUrl}}. Intenta cambiar la respuesta para redirigir a un evento",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Enrutadas por período",
|
||||
"per_day": "Por día",
|
||||
"per_week": "Por semana",
|
||||
"per_month": "Por mes",
|
||||
"per_month": "por mes",
|
||||
"routing_form_insights_assignment_reason": "Motivo de asignación",
|
||||
"access_denied": "Acceso denegado",
|
||||
"salesforce_route_to_owner": "El propietario del contacto será el anfitrión de Round Robin si está disponible",
|
||||
"salesforce_add_attendees_as": "Agregar nuevos asistentes como",
|
||||
"salesforce_do_not_route_to_owner": "El propietario del contacto no será forzado (aún puede ser anfitrión si coincide con los atributos y criterios de Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Dirigir a un usuario que coincida con un campo de búsqueda en una cuenta",
|
||||
"salesforce_option": "Opción de Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Déficit",
|
||||
"routing_form": "Formulario de enrutamiento",
|
||||
"go_back_and_save": "Volver y guardar",
|
||||
"save_changes": "Guardar cambios",
|
||||
"leave_without_saving": "Salir sin guardar",
|
||||
"leave_without_saving_description": "¿Estás seguro de que quieres salir sin guardar los cambios en tu formulario de enrutamiento?",
|
||||
"something_unexpected_occurred": "Ocurrió algo inesperado",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autorizar",
|
||||
"next": "Siguiente",
|
||||
"hide": "Ocultar",
|
||||
"show": "Mostrar",
|
||||
"utm_params": "Parámetros UTM",
|
||||
"no_utm_params": "No hay parámetros UTM disponibles.",
|
||||
"asc": "Asc",
|
||||
"desc": "Desc",
|
||||
"verify_email_change": "Verificar cambio de correo electrónico",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Necesitas tener un mínimo de equipos publicados",
|
||||
"you_are_part_of_this_organization_already": "Ya eres parte de esta organización",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Eres parte de otra organización, no puedes crear una nueva organización",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Eres parte de otra organización de plataforma, no puedes crear una nueva organización",
|
||||
"organization_payment_success": "Pago de la organización exitoso",
|
||||
"organization_payment_success_description": "Tu organización ha sido creada exitosamente",
|
||||
"this_may_take_a_few_seconds": "Esto puede tomar unos segundos...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "La incorporación de la organización ya se completó",
|
||||
"organization_onboarding_already_exists": "La incorporación de la organización ya existe",
|
||||
"organization_onboarding_not_found": "No se encontró la incorporación de la organización",
|
||||
"payment_successful": "Pago exitoso",
|
||||
"payment_successful": "¡Pago exitoso!",
|
||||
"handover_onboarding_page_title": "Traspaso de incorporación",
|
||||
"handover_onboarding_page_description": "Traspaso de incorporación al usuario",
|
||||
"organization_already_exists_with_this_slug": "Ya existe una organización con este slug",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Enlace",
|
||||
"rows_per_page": "filas por página",
|
||||
"pagination_status": "{{currentRange}} de {{totalItems}}",
|
||||
"tip_username_plus": "Consejo: Puedes usar un '+' entre nombres de usuario: cal.com/anna+brian para crear una reunión grupal dinámica",
|
||||
"tip_username_plus": "Consejo: Puedes agregar un '+' entre nombres de usuario: cal.com/anna+brian para crear una reunión grupal dinámica",
|
||||
"user_has_no_team_yet": "Aún no tienes un equipo",
|
||||
"no_team_members": "Aún no tienes miembros en tu equipo",
|
||||
"recurring_event_doesnt_support_seats": "Los eventos recurrentes no admiten la función de asientos. Hazlo no recurrente para habilitar asientos.",
|
||||
"seats_doesnt_support_recurring": "La función de asientos no admite eventos recurrentes. Desactiva la función de asientos para hacerlo recurrente.",
|
||||
"recurring_event_seats_error": "Los eventos recurrentes no admiten la función de asientos. Desactiva la función de asientos o haz que el evento no sea recurrente.",
|
||||
"segment": "Segmento",
|
||||
"rename": "Renombrar",
|
||||
"rename_segment": "Renombrar segmento",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Reservas más canceladas",
|
||||
"name_or_email": "Nombre o correo electrónico",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Si no se encuentra ningún contacto, recurrir al propietario del lead si existe",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agrega tus nuevas cadenas arriba de esta línea ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Fecha y hora",
|
||||
"email_reminder_upcoming_event_notice" : "Este es un recordatorio sobre tu próximo evento.",
|
||||
"email_reminder_triggered_by_workflow" : "Este recordatorio fue activado por un Workflow en Cal.",
|
||||
"enable_delegation_credential": "Habilitar credencial de delegación",
|
||||
"enable_delegation_credential_description": "Otorga a Cal.com acceso automático a los calendarios de todos los miembros de la organización habilitando la credencial de delegación.",
|
||||
"disable_delegation_credential": "Deshabilitar credencial de delegación",
|
||||
"disable_delegation_credential_description": "Una vez que se deshabilita la credencial de delegación, los miembros de la organización que no hayan conectado sus calendarios deberán hacerlo manualmente.",
|
||||
"last_active": "Última actividad",
|
||||
"member_since": "Miembro desde",
|
||||
"last_updated": "Última actualización",
|
||||
"salesforce_on_cancel_write_to_event": "Al cancelar una reserva, escribir en el registro del evento en lugar de eliminarlo",
|
||||
"salesforce_on_every_cancellation": "En cada cancelación",
|
||||
"report_issue": "Reportar problema",
|
||||
"report_issue_description": "Puedes enviar un ticket en GitHub o actualizar tu plan para recibir soporte en tiempo real con conferencias de desarrolladores",
|
||||
"open_issue": "Abrir problema",
|
||||
"this_is_your_current_plan": "Este es tu plan actual",
|
||||
"schedule_a_time": "Programar una hora",
|
||||
"this_includes": "Esto incluye:",
|
||||
"oauth_client_updated_successfully": "Cliente OAuth actualizado correctamente",
|
||||
"oauth_client_not_found": "Cliente OAuth no encontrado.",
|
||||
"subscribe_to_platform": "Suscribirse a la plataforma",
|
||||
"error_accessing_webhooks": "Error al intentar acceder a los webhooks.",
|
||||
"webhook_update_failed": "No se pudo actualizar el webhook.",
|
||||
"webhook_create_failed": "No se pudo crear el webhook.",
|
||||
"invalid_link": "Enlace inválido",
|
||||
"currently_subscribed_to_plan": "Actualmente estás suscrito al plan {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Usuario/Equipo",
|
||||
"client_id_copied": "¡ID del cliente copiado!",
|
||||
"client_secret_copied": "¡Secreto del cliente copiado!",
|
||||
"maintenance_message": "El equipo de Cal.com está realizando mantenimiento programado. Si tienes alguna pregunta, por favor contacta a soporte.",
|
||||
"your_payment_failed": "Tu pago falló",
|
||||
"check_your_inbox": "Revisa tu bandeja de entrada",
|
||||
"account_created_premium_not_reserved": "Tu cuenta ha sido creada, pero tu premium no ha sido reservado.",
|
||||
"email_sent_with_activation_link": "Hemos enviado un correo electrónico a {{email}} con un enlace para activar tu cuenta.",
|
||||
"activate_account_to_purchase_username": "Una vez que actives tu cuenta, podrás intentar comprar tu nombre de usuario premium nuevamente o seleccionar uno diferente.",
|
||||
"open_in_gmail": "Abrir en Gmail",
|
||||
"dont_see_email": "¿No ves un correo electrónico?",
|
||||
"resend_in_seconds": "Reenviar en {{seconds}} segundos",
|
||||
"resend": "Reenviar",
|
||||
"verification_email_sent": "Correo de verificación enviado",
|
||||
"select_all_members": "Seleccionar todos los miembros",
|
||||
"select_all_members_tooltip": "Seleccionar todos los miembros agregará a todos los futuros miembros del equipo cuando se añadan al equipo.",
|
||||
"form_settings": "Configuración del formulario",
|
||||
"remove_whitelist_status": "Eliminar estado de lista blanca",
|
||||
"whitelist_user_workflows": "Incluir flujos de trabajo de usuario en lista blanca",
|
||||
"user_workflows_whitelisted": "Flujos de trabajo de usuario incluidos en lista blanca",
|
||||
"user_workflows_unwhitelisted": "Flujos de trabajo de usuario eliminados de lista blanca",
|
||||
"date_and_time": "Fecha y hora",
|
||||
"email_reminder_upcoming_event_notice": "Este es un recordatorio sobre tu próximo evento.",
|
||||
"email_reminder_triggered_by_workflow": "Este recordatorio fue activado por un Workflow en Cal.",
|
||||
"event_upper_case": "Evento",
|
||||
"scheduling_by": "Programado por",
|
||||
"experience_review_prompt": "¿Cómo fue tu última experiencia?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "¿Qué tan satisfecho estuviste con tu última reunión?",
|
||||
"meeting_not_joined_question": "¿no asististe a la reunión?",
|
||||
"reschedule_cta_short": "Reprograma aquí.",
|
||||
"hide_organizer_email": "Ocultar correo del organizador",
|
||||
"platform_customer_cant_create_organization": "Ya formas parte de una organización de plataforma, por lo que no puedes crear una nueva organización. Cada usuario solo puede pertenecer a una organización. Por favor, crea una nueva cuenta de cal.com con un correo electrónico diferente y usa esa cuenta para suscribirte al plan de organizaciones.",
|
||||
"organization_customer_cant_create_platform": "Ya formas parte de una organización, por lo que no puedes crear una organización de plataforma. Cada usuario solo puede pertenecer a una organización. Por favor, crea una nueva cuenta de cal.com con un correo electrónico diferente y usa esa cuenta para suscribirte al plan de plataforma.",
|
||||
"hide_organizer_email_description": "Ocultar la dirección de correo electrónico del organizador en la pantalla de reserva, notificaciones por correo electrónico y eventos del calendario",
|
||||
"you_and_conjunction": "Tú &",
|
||||
"email_survey_triggered_by_workflow": "Esta encuesta se activó mediante un Workflow en Cal."
|
||||
"select_verified_email": "Seleccionar un correo electrónico verificado",
|
||||
"custom_reply_to_email_title": "Correo 'Responder a' personalizado",
|
||||
"custom_reply_to_email_description": "Usar una dirección de correo electrónico diferente como destinatario de respuesta para los correos de confirmación en lugar del correo del organizador",
|
||||
"email_survey_triggered_by_workflow": "Esta encuesta se activó mediante un Workflow en Cal.",
|
||||
"skip_trial": "Omitir período de prueba",
|
||||
"team_trials_skipped_successfully": "Períodos de prueba del equipo omitidos exitosamente",
|
||||
"sms_workflow_consent": "Al ingresar tu número de teléfono, consientes recibir mensajes SMS para este evento. Pueden aplicarse tarifas de SMS.",
|
||||
"routing_preview_more_info_found_insights": "Más información disponible en <0>Estadísticas de enrutamiento</0>",
|
||||
"results": "Resultados",
|
||||
"view_form": "Ver formulario",
|
||||
"sms_opt_out_message": "Envía STOP para cancelar los mensajes SMS",
|
||||
"routing_form_next_in_queue": "{{count}} siguiente(s) en cola",
|
||||
"routing_form_select_members_to_email": "Enviar respuestas por correo electrónico a",
|
||||
"routing_incomplete_booking_tab": "Reservas incompletas",
|
||||
"include_no_show_in_rr_calculation": "Incluir reservas sin asistencia en los cálculos de round robin",
|
||||
"matching": "Coincidencia",
|
||||
"event_redirect": "Redirección de evento",
|
||||
"reset_form": "Restablecer formulario",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agrega tus nuevas cadenas arriba de esta línea ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Su nombre completo",
|
||||
"no_name": "Sin nombre",
|
||||
"enter_number_between_range": "Introduzca un número entre 1 y {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Rápido y sencillo - no se requiere cuenta. Perfecto para reuniones puntuales.",
|
||||
"email_address": "Email",
|
||||
"enter_valid_email": "Ingresa un correo electrónico válido",
|
||||
"please_schedule_future_call": "Por favor, programa una llamada futura si no estamos disponibles en {{seconds}} segundos",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "En persona (dirección del asistente)",
|
||||
"somewhere_else": "Otro lugar",
|
||||
"custom_attendee_location": "Ubicación personalizada del asistente",
|
||||
"continue_as_guest": "Continuar como invitado",
|
||||
"any_location": "Cualquier ubicación",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Equipo Actualizado Correctamente",
|
||||
"your_team_updated_successfully": "Tu equipo ha sido actualizado con éxito.",
|
||||
"your_org_updated_successfully": "Su organización se ha actualizado correctamente.",
|
||||
"error_copying_to_clipboard": "Error al copiar al portapapeles",
|
||||
"about": "Acerca de",
|
||||
"team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.",
|
||||
"organization_id": "ID de la organización",
|
||||
"organization_id_copied": "ID de la organización copiado.",
|
||||
"org_description": "Algunas frases sobre su organización. Esto aparecerá en la página de la URL de su organización.",
|
||||
"team_id": "ID del equipo",
|
||||
"team_id_copied": "ID del equipo copiado.",
|
||||
"members": "Miembros",
|
||||
"organization_members": "Miembros de Organization",
|
||||
"member": "Miembro",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "¿Estás seguro de que quieres eliminar este miembro del equipo?",
|
||||
"confirm_disband_team": "Sí, Disolver Equipo",
|
||||
"confirm_remove_member": "Sí, Eliminar Miembro",
|
||||
"confirm_subscription_cancellation": "Sí, cancelar suscripción",
|
||||
"cancel_subscription": "Cancelar suscripción",
|
||||
"cancel_subscription_description": "Al cancelar tu suscripción se desactivará permanentemente tu plan actual. Esta acción no se puede deshacer.",
|
||||
"remove_member": "Eliminar Miembro",
|
||||
"manage_your_team": "Administra tu Equipo",
|
||||
"no_teams": "Todavía no tienes ningún equipo.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "URL de tu página de reservas",
|
||||
"booking_cancel_redirect_uri": "URL de la página donde tus usuarios pueden cancelar su reserva",
|
||||
"booking_reschedule_redirect_uri": "URL de la página donde tus usuarios pueden reprogramar su reserva",
|
||||
"booking_conflict_error": "Este horario ya no está disponible. Por favor, regresa a la página anterior y selecciona otro horario.",
|
||||
"open_invitations": "Invitaciones Abiertas",
|
||||
"new_team": "Nuevo Equipo",
|
||||
"create_first_team_and_invite_others": "Cree su primer equipo e invite a otros usuarios a trabajar juntos.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Tu cuenta se creó mediante un Proveedor de Identidad.",
|
||||
"account_managed_by_identity_provider": "Tu cuenta es administrada por {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Para cambiar tu correo electrónico, contraseña, habilitar la autenticación de doble factor y más, por favor visita la configuración de tu cuenta de {{provider}}.",
|
||||
"account_managed_by_identity_provider_error": "Tu cuenta está gestionada por un proveedor de identidad diferente. Intenta iniciar sesión con {{provider}}.",
|
||||
"user_creation_error": "Error al crear un nuevo usuario. Por favor, inténtalo de nuevo.",
|
||||
"signin_with_google": "Iniciar sesión con Google",
|
||||
"signin_with_saml": "Iniciar sesión con SAML",
|
||||
"signin_with_saml_oidc": "Inicie sesión con SAML/OIDC",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "¡Ya está listo!",
|
||||
"install_zapier_app": "Instale primero la aplicación Zapier desde la App Store.",
|
||||
"install_make_app": "Instale primero la aplicación Make desde la App Store.",
|
||||
"app_installation": "Instalación de la aplicación",
|
||||
"app_not_installed": "Aplicación no instalada",
|
||||
"visit_our_app_store": "Lo sentimos, esta aplicación no está instalada en tu cuenta. Por favor visita nuestra tienda de aplicaciones para explorar y descubrir esta y otras grandes aplicaciones.",
|
||||
"connect_apple_server": "Conectar con Apple Server",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "cuando se cancela el evento",
|
||||
"after_hosts_cal_video_no_show": "Después de que los anfitriones no se unieron al video de Cal",
|
||||
"after_guests_cal_video_no_show": "Después de que los invitados no se unieron al video de Cal",
|
||||
"join_video_call": "Unirse a la videollamada",
|
||||
"sign_in_to_cal_com": "Inicia sesión en tu cuenta de Cal.com",
|
||||
"log_in_to_cal_com": "Iniciar sesión en Cal.com",
|
||||
"track_your_meetings": "Haz seguimiento de tus reuniones, recibe notificaciones y gestiona tu agenda de manera más efectiva.",
|
||||
"choose_how_you_d_like_to_join_call": "Elige cómo te gustaría unirte a esta llamada",
|
||||
"new_event_trigger": "cuando se reserva un nuevo evento",
|
||||
"email_host_action": "enviar correo electrónico al anfitrión",
|
||||
"email_attendee_action": "enviar correo electrónico a los asistentes",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Personalizado",
|
||||
"reminder": "Recordatorio",
|
||||
"rescheduled": "Reprogramado",
|
||||
"rescheduled_by": "Reprogramado por",
|
||||
"original_booking": "Reserva original",
|
||||
"completed": "Completado",
|
||||
"rating": "Calificación",
|
||||
"reminder_email": "Recordatorio: {{eventType}} con {{name}} el {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "El flujo de trabajo {{workflowName}} se ha activado {{offOn}} con éxito",
|
||||
"download_responses": "Descargar respuestas",
|
||||
"download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.",
|
||||
"view_responses": "Ver respuestas",
|
||||
"download": "Descargar",
|
||||
"downloading": "Descargando",
|
||||
"download_recording": "Descargar grabación",
|
||||
"transcription_enabled": "Las transcripciones están habilitadas ahora",
|
||||
"transcription_stopped": "Las transcripciones están detenidas ahora",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Añada un nuevo formulario a su equipo",
|
||||
"create_your_first_route": "Cree su primera ruta",
|
||||
"route_to_the_right_person": "Ruta a la persona adecuada en función de las respuestas a su formulario",
|
||||
"form": "Formulario",
|
||||
"form_description": "Crea tu formulario para dirigirlo a un agente de reservas",
|
||||
"copy_link_to_form": "Copiar enlace al formulario",
|
||||
"theme": "Tema de la página de reserva",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Código de verificación incorrecto",
|
||||
"not_verified": "Aún no se ha verificado",
|
||||
"no_availability_in_month": "Sin disponibilidad en {{month}}",
|
||||
"no_availability_rolling": "La programación solo está disponible hasta {{days}} días por adelantado. Por favor, vuelve a consultar pronto.",
|
||||
"no_availability_range": "La programación terminó el {{date}}. Por favor, comprueba de nuevo pronto.",
|
||||
"view_previous_month": "Ver mes anterior",
|
||||
"view_next_month": "Ver el próximo mes",
|
||||
"send_code": "Enviar código",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Ya no es posible pagar por este evento",
|
||||
"booking_with_payment_cancelled_already_paid": "Un reembolso por el pago de esta reserva está en camino.",
|
||||
"booking_with_payment_cancelled_refunded": "El pago de esta reserva se ha reembolsado.",
|
||||
"booking_with_payment_cancelled_no_refund": "Según la política de reembolso del evento, el pago de la reserva no es reembolsable.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "El período de reembolso del evento ha expirado. Por lo tanto, el pago de la reserva no es reembolsable.",
|
||||
"booking_confirmation_failed": "Error al confirmar la reserva",
|
||||
"not_enough_seats": "No hay suficientes plazas",
|
||||
"form_builder_field_already_exists": "Ya existe un campo con este nombre",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Abrir disponibilidad de usuarios",
|
||||
"organization_no_slots_notification_switch_title": "Recibir notificaciones cuando tu equipo no tenga disponibilidad",
|
||||
"organization_no_slots_notification_switch_description": "Los administradores recibirán notificaciones por correo electrónico cuando un usuario intente reservar con un miembro del equipo y no haya disponibilidad. Enviamos este correo después de dos intentos y te recordamos cada 7 días por usuario.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Desactivar notificaciones SMS para tipos de eventos solo con teléfono",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Desactivar notificaciones SMS automáticas para tipos de eventos que solo tienen número de teléfono (attendeePhoneNumber) como pregunta obligatoria con correo electrónico opcional o no requerido",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} te ha añadido a la organización {{team}} en {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} te ha invitado a unirte a la organización {{team}} en {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} te ha añadido al equipo {{team}} de la organización {{parentTeamName}} en {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Tu enlace ha cambiado de {{a0}} a {{a1}} pero no te preocupes, todos los enlaces anteriores siguen funcionando y redireccionando adecuadamente. <br /><br />Ten en cuenta: Todos tus tipos de eventos personales se han movido a la organización <strong>{{teamName}}</strong>, lo que también puede incluir un posible enlace personal.<br /><br />Por favor, inicia sesión y asegúrate de que no tienes eventos privados en tu nueva cuenta organizacional.<br /><br />Para eventos personales, recomendamos crear una nueva cuenta con una dirección de correo electrónico personal.<br /><br />Disfruta de tu nuevo enlace limpio: {{a2}}",
|
||||
"email_organization_created|subject": "Tu organización ha sido creada",
|
||||
"your_current_plan": "Tu plan actual",
|
||||
"organization_price_per_user_month": "$37 por usuario al mes (mínimo 30 asientos)",
|
||||
"organization_price_per_user_month": "$37 por usuario al mes",
|
||||
"privacy_organization_description": "Gestiona la configuración de privacidad para tu organización",
|
||||
"privacy": "Privacidad",
|
||||
"team_will_be_under_org": "Los nuevos equipos estarán bajo tu organización",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Al continuar, aceptas nuestros",
|
||||
"terms": "Términos",
|
||||
"always_show_x_days": "Siempre {{x}} días disponibles",
|
||||
"team_subscription_cancelled_successfully": "Suscripción del equipo cancelada con éxito",
|
||||
"team_subscription_cancellation_error": "Error al cancelar la suscripción del equipo",
|
||||
"unable_to_subscribe_to_the_platform": "Ocurrió un error al intentar suscribirse al plan de la plataforma, por favor intente de nuevo más tarde",
|
||||
"updating_oauth_client_error": "Ocurrió un error al actualizar el cliente OAuth, por favor intente de nuevo más tarde",
|
||||
"creating_oauth_client_error": "Ocurrió un error al crear el cliente OAuth, por favor intente de nuevo más tarde",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Omitir la creación del registro de {{entry}} si no existe en Salesforce",
|
||||
"salesforce_if_account_does_not_exist": "Si el contacto no existe bajo una cuenta, crear un nuevo cliente potencial a partir del asistente",
|
||||
"salesforce_create_new_contact_under_account": "Crear un nuevo contacto bajo una cuenta basado en el dominio de correo electrónico del asistente y los contactos existentes",
|
||||
"salesforce_change_record_owner_on_booking": "Cambiar propietario del registro en la reserva",
|
||||
"mass_assign_attributes": "Asignar atributos en masa",
|
||||
"reroute_preview_custom_message": "Resulta en mostrar un mensaje personalizado. Intenta cambiar la respuesta para redirigir a un evento",
|
||||
"reroute_preview_external_redirect": "Resulta en redirigir a {{externalUrl}}. Intenta cambiar la respuesta para redirigir a un evento",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Enrutado a por período",
|
||||
"per_day": "Por día",
|
||||
"per_week": "Por semana",
|
||||
"per_month": "Por mes",
|
||||
"per_month": "al mes",
|
||||
"routing_form_insights_assignment_reason": "Motivo de asignación",
|
||||
"access_denied": "Acceso denegado",
|
||||
"salesforce_route_to_owner": "El propietario del contacto será el anfitrión de Round Robin si está disponible",
|
||||
"salesforce_add_attendees_as": "Añadir nuevos asistentes como",
|
||||
"salesforce_do_not_route_to_owner": "No se forzará al propietario del contacto (aún puede ser anfitrión si coincide con los atributos y criterios de Round Robin)",
|
||||
"salesforce_route_to_custom_lookup_field": "Dirigir a un usuario que coincida con un campo de búsqueda en una cuenta",
|
||||
"salesforce_option": "Opción de Salesforce",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Déficit",
|
||||
"routing_form": "Formulario de enrutamiento",
|
||||
"go_back_and_save": "Volver y guardar",
|
||||
"save_changes": "Guardar cambios",
|
||||
"leave_without_saving": "Salir sin guardar",
|
||||
"leave_without_saving_description": "¿Estás seguro de que quieres salir sin guardar los cambios en tu formulario de enrutamiento?",
|
||||
"something_unexpected_occurred": "Algo inesperado ha ocurrido",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autorizar",
|
||||
"next": "Siguiente",
|
||||
"hide": "Ocultar",
|
||||
"show": "Mostrar",
|
||||
"utm_params": "Parámetros UTM",
|
||||
"no_utm_params": "No hay parámetros UTM disponibles.",
|
||||
"asc": "Asc",
|
||||
"desc": "Desc",
|
||||
"verify_email_change": "Verificar cambio de correo electrónico",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Necesitas tener un mínimo de equipos publicados",
|
||||
"you_are_part_of_this_organization_already": "Ya formas parte de esta organización",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Formas parte de otra organización, no puedes crear una nueva",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Formas parte de otra organización de plataforma, no puedes crear una nueva organización",
|
||||
"organization_payment_success": "Pago de la organización exitoso",
|
||||
"organization_payment_success_description": "Tu organización se ha creado con éxito",
|
||||
"this_may_take_a_few_seconds": "Esto puede tardar unos segundos...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "La incorporación de la organización ya se ha completado",
|
||||
"organization_onboarding_already_exists": "La incorporación de la organización ya existe",
|
||||
"organization_onboarding_not_found": "No se encontró la incorporación de la organización",
|
||||
"payment_successful": "Pago exitoso",
|
||||
"payment_successful": "¡Pago exitoso!",
|
||||
"handover_onboarding_page_title": "Traspaso de incorporación",
|
||||
"handover_onboarding_page_description": "Traspaso de incorporación al usuario",
|
||||
"organization_already_exists_with_this_slug": "Ya existe una organización con este slug",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Enlace",
|
||||
"rows_per_page": "filas por página",
|
||||
"pagination_status": "{{currentRange}} de {{totalItems}}",
|
||||
"tip_username_plus": "Consejo: Puedes usar un '+' entre nombres de usuario: cal.com/anna+brian para crear una reunión de grupo dinámica",
|
||||
"tip_username_plus": "Consejo: Puedes añadir un '+' entre nombres de usuario: cal.com/anna+brian para crear una reunión grupal dinámica",
|
||||
"user_has_no_team_yet": "Aún no tienes un equipo",
|
||||
"no_team_members": "Aún no tienes miembros en tu equipo",
|
||||
"recurring_event_doesnt_support_seats": "Los eventos recurrentes no admiten la función de asientos. Hazlo no recurrente para habilitar asientos.",
|
||||
"seats_doesnt_support_recurring": "La función de asientos no admite eventos recurrentes. Desactiva la función de asientos para hacerlo recurrente.",
|
||||
"recurring_event_seats_error": "Los eventos recurrentes no admiten la función de asientos. Desactiva la función de asientos o haz que el evento no sea recurrente.",
|
||||
"segment": "Segmento",
|
||||
"rename": "Renombrar",
|
||||
"rename_segment": "Renombrar segmento",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Reservas más canceladas",
|
||||
"name_or_email": "Nombre o correo electrónico",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Si no se encuentra ningún contacto, recurrir al propietario del lead si existe",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agregue sus nuevas cadenas arriba ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Fecha y hora",
|
||||
"email_reminder_upcoming_event_notice" : "Este es un recordatorio sobre su próximo evento.",
|
||||
"email_reminder_triggered_by_workflow" : "Este recordatorio fue activado por un flujo de trabajo en Cal.",
|
||||
"enable_delegation_credential": "Habilitar credencial de delegación",
|
||||
"enable_delegation_credential_description": "Concede a Cal.com acceso automático a los calendarios de todos los miembros de la organización habilitando la credencial de delegación.",
|
||||
"disable_delegation_credential": "Deshabilitar credencial de delegación",
|
||||
"disable_delegation_credential_description": "Una vez que se deshabilita la credencial de delegación, los miembros de la organización que no hayan conectado sus calendarios deberán hacerlo manualmente.",
|
||||
"last_active": "Última actividad",
|
||||
"member_since": "Miembro desde",
|
||||
"last_updated": "Última actualización",
|
||||
"salesforce_on_cancel_write_to_event": "Al cancelar la reserva, escribir en el registro del evento en lugar de eliminarlo",
|
||||
"salesforce_on_every_cancellation": "En cada cancelación",
|
||||
"report_issue": "Informar de un problema",
|
||||
"report_issue_description": "Puedes enviar un ticket en GitHub o actualizar tu plan para recibir soporte en tiempo real con conferencias de desarrolladores",
|
||||
"open_issue": "Abrir incidencia",
|
||||
"this_is_your_current_plan": "Este es tu plan actual",
|
||||
"schedule_a_time": "Programar una hora",
|
||||
"this_includes": "Esto incluye:",
|
||||
"oauth_client_updated_successfully": "Cliente OAuth actualizado correctamente",
|
||||
"oauth_client_not_found": "Cliente OAuth no encontrado.",
|
||||
"subscribe_to_platform": "Suscribirse a la plataforma",
|
||||
"error_accessing_webhooks": "Error al intentar acceder a los webhooks.",
|
||||
"webhook_update_failed": "Error al actualizar el webhook.",
|
||||
"webhook_create_failed": "Error al crear el webhook.",
|
||||
"invalid_link": "Enlace no válido",
|
||||
"currently_subscribed_to_plan": "Actualmente estás suscrito al plan {{planFirstLetter}}{{planRest}}",
|
||||
"user_team": "Usuario/Equipo",
|
||||
"client_id_copied": "¡ID de cliente copiado!",
|
||||
"client_secret_copied": "¡Secreto de cliente copiado!",
|
||||
"maintenance_message": "El equipo de Cal.com está realizando mantenimiento programado. Si tienes alguna pregunta, contacta con soporte.",
|
||||
"your_payment_failed": "Tu pago ha fallado",
|
||||
"check_your_inbox": "Revisa tu bandeja de entrada",
|
||||
"account_created_premium_not_reserved": "Tu cuenta ha sido creada, pero tu premium no ha sido reservado.",
|
||||
"email_sent_with_activation_link": "Hemos enviado un correo electrónico a {{email}} con un enlace para activar tu cuenta.",
|
||||
"activate_account_to_purchase_username": "Una vez que actives tu cuenta, podrás intentar comprar tu nombre de usuario premium nuevamente o seleccionar uno diferente.",
|
||||
"open_in_gmail": "Abrir en Gmail",
|
||||
"dont_see_email": "¿No ves un correo electrónico?",
|
||||
"resend_in_seconds": "Reenviar en {{seconds}} segundos",
|
||||
"resend": "Reenviar",
|
||||
"verification_email_sent": "Correo de verificación enviado",
|
||||
"select_all_members": "Seleccionar todos los miembros",
|
||||
"select_all_members_tooltip": "Al seleccionar todos los miembros se añadirán todos los futuros miembros del equipo cuando se agreguen al equipo.",
|
||||
"form_settings": "Configuración del formulario",
|
||||
"remove_whitelist_status": "Eliminar estado de lista blanca",
|
||||
"whitelist_user_workflows": "Incluir flujos de trabajo de usuario en lista blanca",
|
||||
"user_workflows_whitelisted": "Flujos de trabajo de usuario incluidos en lista blanca",
|
||||
"user_workflows_unwhitelisted": "Flujos de trabajo de usuario eliminados de lista blanca",
|
||||
"date_and_time": "Fecha y hora",
|
||||
"email_reminder_upcoming_event_notice": "Este es un recordatorio sobre su próximo evento.",
|
||||
"email_reminder_triggered_by_workflow": "Este recordatorio fue activado por un flujo de trabajo en Cal.",
|
||||
"event_upper_case": "Evento",
|
||||
"scheduling_by": "Programado por",
|
||||
"experience_review_prompt": "¿Cómo fue tu experiencia reciente?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "¿Qué tan satisfecho estuvo con su última reunión?",
|
||||
"meeting_not_joined_question": "¿no asististe a la reunión?",
|
||||
"reschedule_cta_short": "Reprogramar aquí.",
|
||||
"hide_organizer_email": "Ocultar correo electrónico del organizador",
|
||||
"platform_customer_cant_create_organization": "Ya formas parte de una organización de plataforma, por lo que no puedes crear una nueva organización. Cada usuario solo puede pertenecer a una organización. Por favor, crea una nueva cuenta de cal.com con un correo electrónico diferente y usa esa cuenta para suscribirte al plan de organizaciones.",
|
||||
"organization_customer_cant_create_platform": "Ya formas parte de una organización, por lo que no puedes crear una organización de plataforma. Cada usuario solo puede pertenecer a una organización. Por favor, crea una nueva cuenta de cal.com con un correo electrónico diferente y usa esa cuenta para suscribirte al plan de plataforma.",
|
||||
"hide_organizer_email_description": "Ocultar la dirección de correo electrónico del organizador en la pantalla de reserva, notificaciones por correo electrónico y eventos del calendario",
|
||||
"you_and_conjunction": "Tú &",
|
||||
"email_survey_triggered_by_workflow": "Esta encuesta fue activada por un Workflow en Cal."
|
||||
"select_verified_email": "Seleccionar un correo electrónico verificado",
|
||||
"custom_reply_to_email_title": "Correo electrónico personalizado para 'Responder a'",
|
||||
"custom_reply_to_email_description": "Usar una dirección de correo electrónico diferente como destinatario de respuesta para los correos de confirmación en lugar del correo del organizador",
|
||||
"email_survey_triggered_by_workflow": "Esta encuesta fue activada por un Workflow en Cal.",
|
||||
"skip_trial": "Omitir período de prueba",
|
||||
"team_trials_skipped_successfully": "Períodos de prueba del equipo omitidos con éxito",
|
||||
"sms_workflow_consent": "Al ingresar tu número de teléfono, consientes recibir mensajes SMS para este evento. Pueden aplicarse tarifas de SMS.",
|
||||
"routing_preview_more_info_found_insights": "Más información disponible en <0>Estadísticas de enrutamiento</0>",
|
||||
"results": "Resultados",
|
||||
"view_form": "Ver formulario",
|
||||
"sms_opt_out_message": "Envía STOP para cancelar los mensajes SMS",
|
||||
"routing_form_next_in_queue": "{{count}} siguiente(s) en cola",
|
||||
"routing_form_select_members_to_email": "Enviar respuestas por correo electrónico a",
|
||||
"routing_incomplete_booking_tab": "Reservas incompletas",
|
||||
"include_no_show_in_rr_calculation": "Incluir reservas no presentadas en los cálculos de round robin",
|
||||
"matching": "Coincidencia",
|
||||
"event_redirect": "Redirección de evento",
|
||||
"reset_form": "Restablecer formulario",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agregue sus nuevas cadenas arriba ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Teie täisnimi",
|
||||
"no_name": "Nimetu",
|
||||
"enter_number_between_range": "Palun sisestage arv vahemikus 1 kuni {{maxOccurences}}",
|
||||
"continue_as_guest_description": "Kiire ja lihtne - kontot pole vaja. Ideaalne ühekordseteks kohtumisteks.",
|
||||
"email_address": "E-posti aadress",
|
||||
"enter_valid_email": "Palun sisesta kehtiv email",
|
||||
"please_schedule_future_call": "Palun planeerige tulevane kõne, kui me pole {{seconds}} sekundi pärast saadaval",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Isiklikult (osaleja aadress)",
|
||||
"somewhere_else": "Mujal",
|
||||
"custom_attendee_location": "Kohandatud osaleja asukoht",
|
||||
"continue_as_guest": "Jätka külalisena",
|
||||
"any_location": "Mis tahes asukoht",
|
||||
"yes": "Jah",
|
||||
"no": "Ei",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Meeskonda värskendati edukalt",
|
||||
"your_team_updated_successfully": "Teie meeskonda on edukalt värskendatud.",
|
||||
"your_org_updated_successfully": "Teie organisatsiooni värskendamine õnnestus.",
|
||||
"error_copying_to_clipboard": "Viga lõikelauale kopeerimisel",
|
||||
"about": "Umbes",
|
||||
"team_description": "Paar lauset teie meeskonna kohta. See kuvatakse teie meeskonna URL-i lehel.",
|
||||
"organization_id": "Organisatsiooni ID",
|
||||
"organization_id_copied": "Organisatsiooni ID kopeeritud.",
|
||||
"org_description": "Paar lauset teie organisatsiooni kohta. See kuvatakse teie organisatsiooni URL-i lehel.",
|
||||
"team_id": "Meeskonna ID",
|
||||
"team_id_copied": "Meeskonna ID kopeeritud.",
|
||||
"members": "Liikmed",
|
||||
"organization_members": "Organisatsiooni liikmed",
|
||||
"member": "liige",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Kas olete kindel, et soovite selle liikme meeskonnast eemaldada?",
|
||||
"confirm_disband_team": "Jah, saada meeskond laiali",
|
||||
"confirm_remove_member": "Jah, eemalda liige",
|
||||
"confirm_subscription_cancellation": "Jah, tühista tellimus",
|
||||
"cancel_subscription": "Tühista tellimus",
|
||||
"cancel_subscription_description": "Tellimuse tühistamine deaktiveerib teie praeguse plaani jäädavalt. Seda toimingut ei saa tagasi võtta.",
|
||||
"remove_member": "Eemalda liige",
|
||||
"manage_your_team": "Juhtige oma meeskonda",
|
||||
"no_teams": "Teil pole veel ühtegi meeskonda.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "Sinu broneerimislehe URL",
|
||||
"booking_cancel_redirect_uri": "URL lehele, kus kasutajad saavad oma broneeringu tühistada",
|
||||
"booking_reschedule_redirect_uri": "URL lehele, kus kasutajad saavad oma broneeringut ümber planeerida",
|
||||
"booking_conflict_error": "See aeg pole enam saadaval. Palun minge tagasi eelmisele lehele ja valige teine aeg.",
|
||||
"open_invitations": "Avatud kutsed",
|
||||
"new_team": "Uus meeskond",
|
||||
"create_first_team_and_invite_others": "Looge oma esimene meeskond ja kutsuge teisi kasutajaid koos töötama.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Teie konto loodi identiteedipakkuja abil.",
|
||||
"account_managed_by_identity_provider": "Teie kontot haldab {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "E-posti aadressi, parooli muutmiseks, kahefaktorilise autentimise ja muu lubamiseks külastage oma teenusepakkuja {{provider}} konto seadeid.",
|
||||
"account_managed_by_identity_provider_error": "Teie kontot haldab teine identiteedipakkuja. Proovige sisse logida teenuse {{provider}} abil.",
|
||||
"user_creation_error": "Viga uue kasutaja loomisel. Palun proovige uuesti.",
|
||||
"signin_with_google": "Logi sisse Google'iga",
|
||||
"signin_with_saml": "Logi sisse SAML-iga",
|
||||
"signin_with_saml_oidc": "Logi sisse SAML-i/OIDC-ga",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Kõik on valmis!",
|
||||
"install_zapier_app": "Palun installige esmalt rakenduste poest Zapieri rakendus.",
|
||||
"install_make_app": "Palun esmalt installige rakendus Make App rakenduste poest.",
|
||||
"app_installation": "Rakenduse installimine",
|
||||
"app_not_installed": "Rakendus pole installitud",
|
||||
"visit_our_app_store": "Vabandust, see rakendus pole teie kontole installitud. Palun külastage meie rakenduste poodi, et uurida ja avastada seda ja teisi suurepäraseid rakendusi.",
|
||||
"connect_apple_server": "Ühenda Apple Serveriga",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "Kui sündmus tühistatakse",
|
||||
"after_hosts_cal_video_no_show": "Pärast seda, kui võõrustajad ei liitunud cal videoga",
|
||||
"after_guests_cal_video_no_show": "Pärast seda, kui külalised ei liitunud cal videoga",
|
||||
"join_video_call": "Liitu videokõnega",
|
||||
"sign_in_to_cal_com": "Logige sisse oma Cal.com kontole",
|
||||
"log_in_to_cal_com": "Logi sisse Cal.com-i",
|
||||
"track_your_meetings": "Jälgige oma kohtumisi, saage teavitusi ja hallake oma ajakava tõhusamalt.",
|
||||
"choose_how_you_d_like_to_join_call": "Valige, kuidas soovite selle kõnega liituda",
|
||||
"new_event_trigger": "kui uus sündmus on broneeritud",
|
||||
"email_host_action": "saada e-kiri hostile",
|
||||
"email_attendee_action": "saada osalejatele e-kiri",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Kohandatud",
|
||||
"reminder": "Meeldetuletus",
|
||||
"rescheduled": "Ümber ajastatud",
|
||||
"rescheduled_by": "Uuesti ajastatud isiku poolt",
|
||||
"original_booking": "Algne broneering",
|
||||
"completed": "Lõpetatud",
|
||||
"rating": "Hinnang",
|
||||
"reminder_email": "Meeldetuletus: {{eventType}} kasutajaga {{name}} kell {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}} töövoog lülitati {{offOn}} edukalt sisse",
|
||||
"download_responses": "Laadi vastused alla",
|
||||
"download_responses_description": "Laadige kõik vastused oma vormile alla CSV-vormingus.",
|
||||
"view_responses": "Vaata vastuseid",
|
||||
"download": "Lae alla",
|
||||
"downloading": "Allalaadimine",
|
||||
"download_recording": "Laadi salvestis alla",
|
||||
"transcription_enabled": "Transkriptsioonid on nüüd lubatud",
|
||||
"transcription_stopped": "Transkriptsioonid on nüüd peatatud",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Lisage oma meeskonda uus vorm",
|
||||
"create_your_first_route": "Loo oma esimene marsruut",
|
||||
"route_to_the_right_person": "Tee vormi vastuste põhjal marsruut õigele inimesele",
|
||||
"form": "Vorm",
|
||||
"form_description": "Loo oma vorm broneerija suunamiseks",
|
||||
"copy_link_to_form": "Kopeeri link vormile",
|
||||
"theme": "Broneerimislehe kujundus",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Vale kinnituskood",
|
||||
"not_verified": "Pole veel kinnitatud",
|
||||
"no_availability_in_month": "Pole saadaval {{kuus}}",
|
||||
"no_availability_rolling": "Ajastamine on saadaval ainult kuni {{days}} ette. Palun kontrollige varsti uuesti.",
|
||||
"no_availability_range": "Aja broneerimine lõppes {{date}}. Palun kontrollige peagi uuesti.",
|
||||
"view_previous_month": "Vaata eelmist kuud",
|
||||
"view_next_month": "Vaata järgmist kuud",
|
||||
"send_code": "Saada kood",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Selle sündmuse eest tasumine pole enam võimalik",
|
||||
"booking_with_payment_cancelled_already_paid": "Selle broneeringu makse tagasimakse on teel.",
|
||||
"booking_with_payment_cancelled_refunded": "See broneeringu makse on tagastatud.",
|
||||
"booking_with_payment_cancelled_no_refund": "Vastavalt sündmuse tagasimaksepoliitikale ei ole broneeringu makse tagastatav.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Sündmuse tagasimakseperiood on lõppenud. Seetõttu ei ole broneeringu makse tagastatav.",
|
||||
"booking_confirmation_failed": "Broneeringu kinnitamine ebaõnnestus",
|
||||
"not_enough_seats": "Pole piisavalt kohti",
|
||||
"form_builder_field_already_exists": "Selle nimega väli on juba olemas",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Ava kasutajate saadavus",
|
||||
"organization_no_slots_notification_switch_title": "Saage märguandeid, kui teie meeskond pole saadaval",
|
||||
"organization_no_slots_notification_switch_description": "Administraatorid saavad meilimärguandeid, kui kasutaja üritab broneerida meeskonnaliiget ja seisab silmitsi olekuga 'Saadaval puudub'. Saadame selle meili pärast kahte juhtumit ja tuletame teile meelde iga 7 päeva tagant kasutaja kohta. ",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Keela SMS-teavitused ainult telefoninumbri sündmuste jaoks",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Keela automaatsed SMS-teavitused sündmuste jaoks, kus on kohustuslik ainult telefoninumber (attendeePhoneNumber) ja e-post on valikuline või mitte nõutav.",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} lisas teid rakenduses {{appName}} organisatsiooni {{team}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} kutsus teid liituma organisatsiooniga {{team}} rakenduses {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} lisas teid organisatsiooni {{parentTeamName}} meeskonda {{team}} rakenduses {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Sinu link on muudetud {{a0}}-lt {{a1}}-ks, kuid ära muretse, kõik varasemad lingid töötavad endiselt ja suunavad vastavalt ümber. <br /><br />Palun pane tähele: Kõik sinu isiklikud sündmuste tüübid on viidud <strong>{{teamName}}</strong> organisatsiooni, mis võib sisaldada ka potentsiaalset isiklikku linki.<br /><br />Palun logi sisse ja veendu, et sul pole uuel organisatsiooni kontol privaatseid sündmusi.<br /><br />Isiklike sündmuste jaoks soovitame luua uue konto isikliku e-posti aadressiga.<br /><br />Naudi oma uut puhast linki: {{a2}}",
|
||||
"email_organization_created|subject": "Teie organisatsioon on loodud",
|
||||
"your_current_plan": "Teie praegune plaan",
|
||||
"organization_price_per_user_month": "37 dollarit kasutaja kohta kuus (minimaalselt 30 kohta)",
|
||||
"organization_price_per_user_month": "$37 kasutaja kohta kuus",
|
||||
"privacy_organization_description": "Oma organisatsiooni privaatsusseadete haldamine",
|
||||
"privacy": "Privaatsus",
|
||||
"team_will_be_under_org": "Teie organisatsiooni alla kuuluvad uued meeskonnad",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Jätkates nõustute meie",
|
||||
"terms": "Tingimustega",
|
||||
"always_show_x_days": "Alati {{x}} päeva saadaval",
|
||||
"team_subscription_cancelled_successfully": "Meeskonna tellimus tühistati edukalt",
|
||||
"team_subscription_cancellation_error": "Viga meeskonna tellimuse tühistamisel",
|
||||
"unable_to_subscribe_to_the_platform": "Platvormipaketi tellimisel ilmnes viga, proovige hiljem uuesti",
|
||||
"updating_oauth_client_error": "OAuthi kliendi värskendamisel ilmnes viga, proovige hiljem uuesti",
|
||||
"creating_oauth_client_error": "OAuthi kliendi loomisel ilmnes viga, proovige hiljem uuesti",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Jäta {{entry}} kirje loomata, kui seda Salesforce'is ei eksisteeri",
|
||||
"salesforce_if_account_does_not_exist": "Kui kontakti ei eksisteeri konto all, loo osaleja andmetest uus müügivihje",
|
||||
"salesforce_create_new_contact_under_account": "Loo uus kontakt konto alla, põhinedes osaleja e-posti domeenile ja olemasolevatele kontaktidele",
|
||||
"salesforce_change_record_owner_on_booking": "Muuda broneeringu kirje omanikku",
|
||||
"mass_assign_attributes": "Massiline atribuutide määramine",
|
||||
"reroute_preview_custom_message": "See toob kaasa kohandatud sõnumi kuvamise. Proovi muuta vastust, et suunata sündmusele",
|
||||
"reroute_preview_external_redirect": "See toob kaasa ümbersuunamise aadressile {{externalUrl}}. Proovi muuta vastust, et suunata sündmusele",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Suunatud perioodi kohta",
|
||||
"per_day": "Päevas",
|
||||
"per_week": "Nädalas",
|
||||
"per_month": "Kuus",
|
||||
"per_month": "kuus",
|
||||
"routing_form_insights_assignment_reason": "Määramise põhjus",
|
||||
"access_denied": "Juurdepääs keelatud",
|
||||
"salesforce_route_to_owner": "Kontakti omanik on round robin host, kui saadaval",
|
||||
"salesforce_add_attendees_as": "Lisa uued osalejad kui",
|
||||
"salesforce_do_not_route_to_owner": "Kontakti omanikku ei sunnita (võib siiski olla host, kui vastab atribuutidele ja round robin kriteeriumitele)",
|
||||
"salesforce_route_to_custom_lookup_field": "Suuna kasutajale, kes vastab konto otsinguväljale",
|
||||
"salesforce_option": "Salesforce'i valik",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Puudujääk",
|
||||
"routing_form": "Marsruutimise vorm",
|
||||
"go_back_and_save": "Mine tagasi ja salvesta",
|
||||
"save_changes": "Salvesta muudatused",
|
||||
"leave_without_saving": "Lahku salvestamata",
|
||||
"leave_without_saving_description": "Kas oled kindel, et soovid lahkuda marsruutimisvormi muudatusi salvestamata?",
|
||||
"something_unexpected_occurred": "Midagi ootamatut juhtus",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Autoriseeri",
|
||||
"next": "Edasi",
|
||||
"hide": "Peida",
|
||||
"show": "Näita",
|
||||
"utm_params": "UTM parameetrid",
|
||||
"no_utm_params": "UTM parameetrid pole saadaval.",
|
||||
"asc": "Kasvav",
|
||||
"desc": "Kahanev",
|
||||
"verify_email_change": "Kinnita e-posti aadressi muutmine",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Teil peab olema minimaalne arv avaldatud meeskondi",
|
||||
"you_are_part_of_this_organization_already": "Te olete juba selle organisatsiooni liige",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Te olete osa teisest organisatsioonist, uut organisatsiooni ei saa luua",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Te olete osa teisest platvormi organisatsioonist, uut organisatsiooni ei saa luua.",
|
||||
"organization_payment_success": "Organisatsiooni makse õnnestus",
|
||||
"organization_payment_success_description": "Teie organisatsioon on edukalt loodud",
|
||||
"this_may_take_a_few_seconds": "See võib võtta mõne sekundi...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Organisatsiooni liitumisprotsess on juba lõpetatud",
|
||||
"organization_onboarding_already_exists": "Organisatsiooni liitumisprotsess on juba olemas",
|
||||
"organization_onboarding_not_found": "Organisatsiooni liitumisprotsessi ei leitud",
|
||||
"payment_successful": "Makse õnnestus",
|
||||
"payment_successful": "Makse õnnestus!",
|
||||
"handover_onboarding_page_title": "Liitumisprotsessi üleandmine",
|
||||
"handover_onboarding_page_description": "Liitumisprotsessi üleandmine kasutajale",
|
||||
"organization_already_exists_with_this_slug": "Selle lühilingiga organisatsioon on juba olemas",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Link",
|
||||
"rows_per_page": "rida lehel",
|
||||
"pagination_status": "{{currentRange}} / {{totalItems}}",
|
||||
"tip_username_plus": "Nõuanne: Saate kasutajanimede vahele lisada '+': cal.com/anna+brian, et luua dünaamiline grupikohtumise",
|
||||
"tip_username_plus": "Nõuanne: saate lisada '+' kasutajanimede vahele: cal.com/anna+brian, et luua dünaamiline grupikoosolek.",
|
||||
"user_has_no_team_yet": "Teil pole veel meeskonda",
|
||||
"no_team_members": "Teil pole veel meeskonnaliikmeid",
|
||||
"recurring_event_doesnt_support_seats": "Korduv sündmus ei toeta kohtade funktsiooni. Muutke see mittekorduvaks, et lubada kohtade funktsioon.",
|
||||
"seats_doesnt_support_recurring": "Kohtade funktsioon ei toeta korduvat sündmust. Keelake kohtade funktsioon, et muuta see korduvaks.",
|
||||
"recurring_event_seats_error": "Korduv sündmus ei toeta kohtade funktsiooni. Keelake kohtade funktsioon või muutke sündmus mittekorduvaks.",
|
||||
"segment": "Segment",
|
||||
"rename": "Nimeta ümber",
|
||||
"rename_segment": "Nimeta segment ümber",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Enim tühistatud broneeringud",
|
||||
"name_or_email": "Nimi või e-post",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Kui kontakti ei leita, kasuta võimalusel liidi omanikku",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Kuupäev ja kellaaeg",
|
||||
"email_reminder_upcoming_event_notice" : "See on meeldetuletus teie eelseisva sündmuse kohta.",
|
||||
"email_reminder_triggered_by_workflow" : "Selle meeldetuletuse käivitas Cali töövoog.",
|
||||
"enable_delegation_credential": "Luba delegeerimise volitus",
|
||||
"enable_delegation_credential_description": "Andke Cal.com-ile automaatne juurdepääs kõigi organisatsiooni liikmete kalendritele, lubades delegeerimise volituse.",
|
||||
"disable_delegation_credential": "Keela delegeerimise volitus",
|
||||
"disable_delegation_credential_description": "Kui delegeerimise volitus on keelatud, peavad organisatsiooni liikmed, kes pole oma kalendreid ühendanud, seda käsitsi tegema.",
|
||||
"last_active": "Viimati aktiivne",
|
||||
"member_since": "Liige alates",
|
||||
"last_updated": "Viimati uuendatud",
|
||||
"salesforce_on_cancel_write_to_event": "Tühistatud broneeringu korral kirjutage sündmuse kirjesse selle asemel, et sündmus kustutada",
|
||||
"salesforce_on_every_cancellation": "Iga tühistamise korral",
|
||||
"report_issue": "Teata probleemist",
|
||||
"report_issue_description": "Saate esitada pileti GitHubis või uuendada oma plaani, et saada reaalajas tuge arendajate konverentsidel",
|
||||
"open_issue": "Ava probleem",
|
||||
"this_is_your_current_plan": "See on teie praegune plaan",
|
||||
"schedule_a_time": "Planeeri aeg",
|
||||
"this_includes": "See sisaldab:",
|
||||
"oauth_client_updated_successfully": "OAuth klient edukalt uuendatud",
|
||||
"oauth_client_not_found": "OAuth klienti ei leitud.",
|
||||
"subscribe_to_platform": "Telli platvorm",
|
||||
"error_accessing_webhooks": "Viga veebikonksudele juurdepääsemisel.",
|
||||
"webhook_update_failed": "Veebikonksu uuendamine ebaõnnestus.",
|
||||
"webhook_create_failed": "Veebikonksu loomine ebaõnnestus.",
|
||||
"invalid_link": "Kehtetu link",
|
||||
"currently_subscribed_to_plan": "Olete praegu tellinud {{planFirstLetter}}{{planRest}} plaani",
|
||||
"user_team": "Kasutaja/Meeskond",
|
||||
"client_id_copied": "Kliendi ID kopeeritud!",
|
||||
"client_secret_copied": "Kliendi saladus kopeeritud!",
|
||||
"maintenance_message": "Cal.com meeskond teostab plaanilist hooldust. Kui teil on küsimusi, võtke ühendust toega.",
|
||||
"your_payment_failed": "Teie makse ebaõnnestus",
|
||||
"check_your_inbox": "Kontrollige oma postkasti",
|
||||
"account_created_premium_not_reserved": "Teie konto on loodud, kuid teie premium ei ole reserveeritud.",
|
||||
"email_sent_with_activation_link": "Oleme saatnud e-kirja aadressile {{email}} koos lingiga teie konto aktiveerimiseks.",
|
||||
"activate_account_to_purchase_username": "Kui aktiveerite oma konto, saate uuesti proovida oma premium kasutajanime osta või valida teise.",
|
||||
"open_in_gmail": "Ava Gmailis",
|
||||
"dont_see_email": "Ei näe e-kirja?",
|
||||
"resend_in_seconds": "Saada uuesti {{seconds}} sekundi pärast",
|
||||
"resend": "Saada uuesti",
|
||||
"verification_email_sent": "Kinnituskiri saadetud",
|
||||
"select_all_members": "Vali kõik liikmed",
|
||||
"select_all_members_tooltip": "Kõigi liikmete valimine lisab kõik tulevased meeskonnaliikmed, kui nad meeskonda lisatakse.",
|
||||
"form_settings": "Vormi seaded",
|
||||
"remove_whitelist_status": "Eemalda lubatud nimekirja staatus",
|
||||
"whitelist_user_workflows": "Lisa kasutaja töövood lubatud nimekirja",
|
||||
"user_workflows_whitelisted": "Kasutaja töövood lisatud lubatud nimekirja",
|
||||
"user_workflows_unwhitelisted": "Kasutaja töövood eemaldatud lubatud nimekirjast",
|
||||
"date_and_time": "Kuupäev ja kellaaeg",
|
||||
"email_reminder_upcoming_event_notice": "See on meeldetuletus teie eelseisva sündmuse kohta.",
|
||||
"email_reminder_triggered_by_workflow": "Selle meeldetuletuse käivitas Cali töövoog.",
|
||||
"event_upper_case": "Sündmus",
|
||||
"scheduling_by": "Plaanitud",
|
||||
"experience_review_prompt": "Kuidas oli teie hiljutine kogemus?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Kui rahul olite oma viimase kohtumisega?",
|
||||
"meeting_not_joined_question": "ei osalenud koosolekul?",
|
||||
"reschedule_cta_short": "Broneeri uuesti siit.",
|
||||
"hide_organizer_email": "Peida korraldaja e-posti aadress",
|
||||
"platform_customer_cant_create_organization": "Te olete juba osa platvormi organisatsioonist, mistõttu te ei saa luua uut organisatsiooni. Iga kasutaja saab kuuluda ainult ühte organisatsiooni. Palun looge uus cal.com konto teise e-posti aadressiga ja kasutage seda kontot organisatsiooni plaaniga liitumiseks.",
|
||||
"organization_customer_cant_create_platform": "Te olete juba osa organisatsioonist, mistõttu te ei saa luua platvormi organisatsiooni. Iga kasutaja saab kuuluda ainult ühte organisatsiooni. Palun looge uus cal.com konto teise e-posti aadressiga ja kasutage seda kontot platvormi plaaniga liitumiseks.",
|
||||
"hide_organizer_email_description": "Peida korraldaja e-posti aadress broneerimisekraanil, e-posti teavitustes ja kalendrisündmustes.",
|
||||
"you_and_conjunction": "Sina &",
|
||||
"email_survey_triggered_by_workflow": "See küsitlus käivitati Cali töövooga."
|
||||
"select_verified_email": "Vali kinnitatud e-posti aadress",
|
||||
"custom_reply_to_email_title": "Kohandatud 'Vasta-aadress' e-post",
|
||||
"custom_reply_to_email_description": "Kasutage kinnituskirjade jaoks vastuse aadressina teist e-posti aadressi, mitte korraldaja e-posti aadressi.",
|
||||
"email_survey_triggered_by_workflow": "See küsitlus käivitati Cali töövooga.",
|
||||
"skip_trial": "Jäta prooviperiood vahele",
|
||||
"team_trials_skipped_successfully": "Meeskonna prooviperioodid edukalt vahele jäetud",
|
||||
"sms_workflow_consent": "Sisestades oma telefoninumbri, annate nõusoleku saada selle sündmuse kohta SMS-sõnumeid. Võivad kehtida SMS-i tariifid.",
|
||||
"routing_preview_more_info_found_insights": "Lisateavet leiate <0>marsruutimise ülevaadetest</0>",
|
||||
"results": "Tulemused",
|
||||
"view_form": "Vaata vormi",
|
||||
"sms_opt_out_message": "SMS-sõnumitest loobumiseks saatke tekst STOP",
|
||||
"routing_form_next_in_queue": "{{count}} järgmine järjekorras",
|
||||
"routing_form_select_members_to_email": "Saada e-posti vastused",
|
||||
"routing_incomplete_booking_tab": "Lõpetamata broneeringud",
|
||||
"include_no_show_in_rr_calculation": "Kaasa mitteilmunud broneeringud round robin arvutustesse",
|
||||
"matching": "Sobitamine",
|
||||
"event_redirect": "Sündmuse ümbersuunamine",
|
||||
"reset_form": "Lähtesta vorm",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Zure izen osoa",
|
||||
"no_name": "Izenik ez",
|
||||
"enter_number_between_range": "Mesedez sartu 1 eta {{maxOccurences}} arteko zenbaki bat",
|
||||
"continue_as_guest_description": "Azkarra eta erraza - ez da konturik behar. Perfektua aldi bakarreko bileretarako.",
|
||||
"email_address": "Email helbidea",
|
||||
"enter_valid_email": "Mesedez, adierazi baliozko email helbide bat",
|
||||
"please_schedule_future_call": "Mesedez, programatu etorkizuneko dei bat {{seconds}} segundotan eskuragarri ez bagaude",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Aurrez aurre (partaidearen helbidean)",
|
||||
"somewhere_else": "Beste nonbait",
|
||||
"custom_attendee_location": "Parte-hartzailearen kokapen pertsonalizatua",
|
||||
"continue_as_guest": "Jarraitu gonbidatu gisa",
|
||||
"any_location": "Edozein kokapen",
|
||||
"yes": "Bai",
|
||||
"no": "Ez",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Taldea egoki eguneratu da",
|
||||
"your_team_updated_successfully": "Zure taldea egoki eguneratu da.",
|
||||
"your_org_updated_successfully": "Zure erakundea egoki eguneratu da.",
|
||||
"error_copying_to_clipboard": "Errorea arbelera kopiatzean",
|
||||
"about": "Honi buruz",
|
||||
"team_description": "Esaldi gutxi batzuk zure taldeari buruz. Zure taldearen orrialdean agertuko dira.",
|
||||
"organization_id": "Erakundearen IDa",
|
||||
"organization_id_copied": "Erakundearen IDa kopiatua.",
|
||||
"org_description": "Esaldi gutxi batzuk zure erakundeari buruz. Zure erakundearen orrialdean agertuko dira.",
|
||||
"team_id": "Taldearen IDa",
|
||||
"team_id_copied": "Taldearen IDa kopiatua.",
|
||||
"members": "Kideak",
|
||||
"organization_members": "Erakundeko kideak",
|
||||
"member": "Kidea",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Ziur zaude kide hau taldetik kendu nahi duzula?",
|
||||
"confirm_disband_team": "Bai, taldea desegin",
|
||||
"confirm_remove_member": "Bai, ezabatu kidea",
|
||||
"confirm_subscription_cancellation": "Bai, ezeztatu harpidetza",
|
||||
"cancel_subscription": "Ezeztatu harpidetza",
|
||||
"cancel_subscription_description": "Zure harpidetza ezeztatzeak zure oraingo plana betiko desaktibatuko du. Ekintza hau ezin da desegin.",
|
||||
"remove_member": "Ezabatu kidea",
|
||||
"manage_your_team": "Kudeatu zure taldea",
|
||||
"no_teams": "Oraindik ez daukazu talderik.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "Zure erreserba orriaren URLa",
|
||||
"booking_cancel_redirect_uri": "Zure erabiltzaileek erreserba bertan behera uzteko orriaren URLa",
|
||||
"booking_reschedule_redirect_uri": "Zure erabiltzaileek erreserba berriz programatzeko orriaren URLa",
|
||||
"booking_conflict_error": "Tarte hau ez dago jada eskuragarri. Mesedez, itzuli aurreko orrira eta aukeratu beste ordu bat.",
|
||||
"open_invitations": "Gonbidapen irekiak",
|
||||
"new_team": "Talde berria",
|
||||
"create_first_team_and_invite_others": "Sortu zure lehen taldea eta gonbidatu beste erabiltzaileak elkarlanean aritzera.",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Zure kontua identitate-hornitzaile baten bidez sortu zen.",
|
||||
"account_managed_by_identity_provider": "Zure kontua {{provider}}-k kudeatzen du",
|
||||
"account_managed_by_identity_provider_description": "Zure emaila, pasahitza aldatzeko, bi faktoreko autentifikazioa gaitzeko eta gehiagorako, joan zure {{provider}} kontuaren ezarpenetara.",
|
||||
"account_managed_by_identity_provider_error": "Zure kontua beste identitate-hornitzaile batek kudeatzen du. Saiatu {{provider}} bidez sartzen.",
|
||||
"user_creation_error": "Errorea erabiltzaile berria sortzean. Mesedez, saiatu berriro.",
|
||||
"signin_with_google": "Hasi saioa Googlerekin",
|
||||
"signin_with_saml": "Hasi saioa SAMLrekin",
|
||||
"signin_with_saml_oidc": "Hasi saioa SAML/OIDCrekin",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Prest zaude!",
|
||||
"install_zapier_app": "Mesedez, lehenik instalatu Zapier App-a app store-an.",
|
||||
"install_make_app": "Mesedez, lehenik instalatu Make App-a app store-an.",
|
||||
"app_installation": "Aplikazioaren instalazioa",
|
||||
"app_not_installed": "Aplikazioa ez dago instalatuta",
|
||||
"visit_our_app_store": "Barkatu, aplikazio hau ez dago instalatuta zure kontuan. Mesedez, bisitatu gure app store-a hau eta beste aplikazio bikain batzuk ezagutzeko.",
|
||||
"connect_apple_server": "Konektatu Apple zerbitzarira",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "gertaera bertan behera geratzen denean",
|
||||
"after_hosts_cal_video_no_show": "Ostalariak Cal bideora batu ez direnean",
|
||||
"after_guests_cal_video_no_show": "Gonbidatuak Cal bideora batu ez direnean",
|
||||
"join_video_call": "Batu bideo-deira",
|
||||
"sign_in_to_cal_com": "Hasi saioa zure Cal.com kontuan",
|
||||
"log_in_to_cal_com": "Hasi saioa Cal.com-en",
|
||||
"track_your_meetings": "Jarraitu zure bilerak, jaso jakinarazpenak, eta kudeatu zure egutegia modu eraginkorragoan.",
|
||||
"choose_how_you_d_like_to_join_call": "Aukeratu nola nahi duzun dei honetara batzea",
|
||||
"new_event_trigger": "gertaera berri bat erreserbatzen denean",
|
||||
"email_host_action": "bidali emaila anfitrioiari",
|
||||
"email_attendee_action": "bidali emaila partaideei",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Pertsonalizatua",
|
||||
"reminder": "Gogorarazlea",
|
||||
"rescheduled": "Berrantolatua",
|
||||
"rescheduled_by": "Honek berrantolatua",
|
||||
"original_booking": "Jatorrizko erreserba",
|
||||
"completed": "Osatuta",
|
||||
"rating": "Balorazioa",
|
||||
"reminder_email": "Gogorarazpena: {{eventType}} {{name}}(r)ekin {{date}}(e)an",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}} lan-fluxua arrakastaz {{offOn}}",
|
||||
"download_responses": "Deskargatu erantzunak",
|
||||
"download_responses_description": "Deskargatu zure formularioko erantzun guztiak CSV formatuan",
|
||||
"view_responses": "Ikusi erantzunak",
|
||||
"download": "Deskargatu",
|
||||
"downloading": "Deskargatzen",
|
||||
"download_recording": "Deskargatu grabaketa",
|
||||
"transcription_enabled": "Transkripzioak aktibatuta daude orain",
|
||||
"transcription_stopped": "Transkripzioak gelditu dira orain",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Gehitu inprimaki berria zure taldeari",
|
||||
"create_your_first_route": "Sortu zure lehen bideratzea",
|
||||
"route_to_the_right_person": "Bideratu pertsona egokiarengana inprimakiaren erantzunen arabera",
|
||||
"form": "Inprimakia",
|
||||
"form_description": "Sortu zure inprimakia erreserbatzailea bideratzeko",
|
||||
"copy_link_to_form": "Kopiatu inprimakiaren esteka",
|
||||
"theme": "Erreserba orriaren itxura",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Egiaztapen kode okerra",
|
||||
"not_verified": "Oraindik egiaztatu gabe",
|
||||
"no_availability_in_month": "Ez dago erabilgarritasunik {{month}} hilabetean",
|
||||
"no_availability_rolling": "Programazioa {{days}} egun aurretik bakarrik dago eskuragarri. Mesedez, begiratu berriro laster.",
|
||||
"no_availability_range": "Hitzorduak {{date}} datan amaitu ziren. Mesedez, begiratu berriro laster.",
|
||||
"view_previous_month": "Ikusi aurreko hilabetea",
|
||||
"view_next_month": "Ikusi hurrengo hilabetea",
|
||||
"send_code": "Bidali kodea",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Ezin da ekitaldi honengatik ordaindu",
|
||||
"booking_with_payment_cancelled_already_paid": "Erreserba honen ordainketaren itzulketa bidean dago.",
|
||||
"booking_with_payment_cancelled_refunded": "Erreserba honen ordainketa itzuli da.",
|
||||
"booking_with_payment_cancelled_no_refund": "Ekitaldiaren itzulketa-politikaren arabera, erreserba ordainketa ez da itzulgarria.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Ekitaldiaren itzulketa-leihoa iraungi da. Beraz, erreserba ordainketa ez da itzulgarria.",
|
||||
"booking_confirmation_failed": "Erreserba berrespena huts egin du",
|
||||
"not_enough_seats": "Ez dago nahikoa eserleku",
|
||||
"form_builder_field_already_exists": "Izen hori duen eremu bat existitzen da dagoeneko",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Open users availability",
|
||||
"organization_no_slots_notification_switch_title": "Jaso jakinarazpenak zure taldeak eskuragarritasunik ez duenean",
|
||||
"organization_no_slots_notification_switch_description": "Administratzaileek mezu elektronikoak jasoko dituzte erabiltzaile batek taldekide bat erreserbatu nahi duenean eta 'Ez dago eskuragarritasunik' mezua agertzen denean. Mezu hau bi aldiz gertatu ondoren bidaltzen dugu eta 7 egunero gogorarazten dizugu erabiltzaile bakoitzeko.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Desgaitu SMS jakinarazpenak telefono-zenbaki soileko ekitaldi-motetan",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Desgaitu SMS jakinarazpen automatikoak telefono zenbakia soilik (attendeePhoneNumber) beharrezko galdera gisa duten ekitaldi-motetan, posta elektronikoa aukerakoa edo ez beharrezkoa izanik",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} added you to the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} invited you to join the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} added you to the team {{team}} of organization {{parentTeamName}} on {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Zure esteka {{a0}}-tik {{a1}}-ra aldatu da, baina ez kezkatu, aurreko esteka guztiek funtzionatzen jarraitzen dute eta behar bezala birbideratzen dira. <br /><br />Kontuan izan: Zure gertaera mota pertsonal guztiak <strong>{{teamName}}</strong> erakundera mugitu dira, eta horrek esteka pertsonal posibleak ere barne har ditzake.<br /><br />Mesedez, hasi saioa eta ziurtatu ez duzula gertaera pribaturik zure erakundeko kontu berrian.<br /><br />Gertaera pertsonaletarako, helbide elektroniko pertsonal batekin kontu berri bat sortzea gomendatzen dugu.<br /><br />Gozatu zure esteka garbi berriaz: {{a2}}",
|
||||
"email_organization_created|subject": "Zure erakundea sortu da",
|
||||
"your_current_plan": "Zure oraingo plana",
|
||||
"organization_price_per_user_month": "37$ erabiltzaile bakoitzeko hilabetean (gutxienez 30 erabiltzaile)",
|
||||
"organization_price_per_user_month": "37$ erabiltzaile bakoitzeko hilabetero",
|
||||
"privacy_organization_description": "Kudeatu zure erakundearen pribatutasun-ezarpenak",
|
||||
"privacy": "Pribatutasuna",
|
||||
"team_will_be_under_org": "Talde berriak zure erakundearen barruan egongo dira",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Jarraituz gero, gure honekin ados zaudela adierazten duzu",
|
||||
"terms": "Baldintzak",
|
||||
"always_show_x_days": "Beti {{x}} egun erabilgarri",
|
||||
"team_subscription_cancelled_successfully": "Taldearen harpidetza behar bezala ezeztatu da",
|
||||
"team_subscription_cancellation_error": "Errorea gertatu da taldearen harpidetza ezeztatzean",
|
||||
"unable_to_subscribe_to_the_platform": "Errore bat gertatu da plataformaren planera harpidetzen saiatzean, saiatu berriro geroago",
|
||||
"updating_oauth_client_error": "Errore bat gertatu da OAuth bezeroa eguneratzean, saiatu berriro geroago",
|
||||
"creating_oauth_client_error": "Errore bat gertatu da OAuth bezeroa sortzean, saiatu berriro geroago",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Saltatu {{entry}} erregistroa sortzea Salesforce-n ez badago",
|
||||
"salesforce_if_account_does_not_exist": "Kontaktua ez badago kontu baten azpian, sortu lead berria parte-hartzailearekin",
|
||||
"salesforce_create_new_contact_under_account": "Sortu kontaktu berria kontu baten azpian parte-hartzailearen email domeinuan eta existitzen diren kontaktuetan oinarrituta",
|
||||
"salesforce_change_record_owner_on_booking": "Aldatu erregistroaren jabea erreserban",
|
||||
"mass_assign_attributes": "Masiboki esleitu atributuak",
|
||||
"reroute_preview_custom_message": "Mezu pertsonalizatua erakusten du. Saiatu erantzuna aldatzen gertaera batera bideratzeko",
|
||||
"reroute_preview_external_redirect": "{{externalUrl}}-ra birbideratzen du. Saiatu erantzuna aldatzen gertaera batera bideratzeko",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Epealdi bakoitzeko birbideratutakoak",
|
||||
"per_day": "Eguneko",
|
||||
"per_week": "Asteko",
|
||||
"per_month": "Hileko",
|
||||
"per_month": "hilabeteko",
|
||||
"routing_form_insights_assignment_reason": "Esleitzeko arrazoia",
|
||||
"access_denied": "Sarbidea ukatuta",
|
||||
"salesforce_route_to_owner": "Kontaktuaren jabea Round Robin ostalaria izango da posible bada",
|
||||
"salesforce_add_attendees_as": "Gehitu parte-hartzaile berriak honela",
|
||||
"salesforce_do_not_route_to_owner": "Kontaktuaren jabea ez da behartuko (ostalaria izan daiteke atributuak eta Round Robin irizpideak betetzen baditu)",
|
||||
"salesforce_route_to_custom_lookup_field": "Kontu bateko bilaketa eremua betetzen duen erabiltzaile batengana bideratu",
|
||||
"salesforce_option": "Salesforce aukera",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Gabezia",
|
||||
"routing_form": "Bideratze-formularioa",
|
||||
"go_back_and_save": "Itzuli eta gorde",
|
||||
"save_changes": "Gorde aldaketak",
|
||||
"leave_without_saving": "Irten gorde gabe",
|
||||
"leave_without_saving_description": "Ziur zaude bideratzeko inprimakian egindako aldaketak gorde gabe irten nahi duzula?",
|
||||
"something_unexpected_occurred": "Ustekabeko zerbait gertatu da",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Baimendu",
|
||||
"next": "Hurrengoa",
|
||||
"hide": "Ezkutatu",
|
||||
"show": "Erakutsi",
|
||||
"utm_params": "UTM parametroak",
|
||||
"no_utm_params": "Ez dago UTM parametrorik eskuragarri.",
|
||||
"asc": "Gorantz",
|
||||
"desc": "Beherantz",
|
||||
"verify_email_change": "Egiaztatu posta elektronikoaren aldaketa",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Argitaratutako gutxieneko talde kopurua izan behar duzu",
|
||||
"you_are_part_of_this_organization_already": "Dagoeneko erakunde honen parte zara",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Beste erakunde baten parte zara, ezin duzu erakunde berri bat sortu",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Beste plataforma-erakunde baten parte zara, ezin duzu erakunde berri bat sortu",
|
||||
"organization_payment_success": "Erakundearen ordainketa arrakastatsua",
|
||||
"organization_payment_success_description": "Zure erakundea arrakastaz sortu da",
|
||||
"this_may_take_a_few_seconds": "Honek segundo batzuk har ditzake...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Erakundearen hasierako prozesua dagoeneko amaituta dago",
|
||||
"organization_onboarding_already_exists": "Erakundearen hasierako prozesua dagoeneko existitzen da",
|
||||
"organization_onboarding_not_found": "Erakundearen hasierako prozesua ez da aurkitu",
|
||||
"payment_successful": "Ordainketa arrakastatsua",
|
||||
"payment_successful": "Ordainketa arrakastatsua!",
|
||||
"handover_onboarding_page_title": "Hasierako prozesuaren eskualdaketa",
|
||||
"handover_onboarding_page_description": "Hasierako prozesua erabiltzaileari eskualdatu",
|
||||
"organization_already_exists_with_this_slug": "Erakunde bat dagoeneko existitzen da slug honekin",
|
||||
@@ -3019,9 +3058,12 @@
|
||||
"link": "Esteka",
|
||||
"rows_per_page": "errenkada orrialdeko",
|
||||
"pagination_status": "{{currentRange}} / {{totalItems}}",
|
||||
"tip_username_plus": "Aholkua: '+' bat jar dezakezu erabiltzaile-izenen artean: cal.com/anna+brian talde-bilera dinamiko bat sortzeko",
|
||||
"tip_username_plus": "Aholkua: '+' bat gehitu dezakezu erabiltzaile-izenen artean: cal.com/anna+brian talde-bilera dinamiko bat sortzeko",
|
||||
"user_has_no_team_yet": "Oraindik ez duzu talderik",
|
||||
"no_team_members": "Oraindik ez dituzu taldekiderik",
|
||||
"recurring_event_doesnt_support_seats": "Ekitaldi errepikakorrak ez du eserlekuen ezaugarria onartzen. Ez-errepikakor bihurtu eserlekuak gaitzeko.",
|
||||
"seats_doesnt_support_recurring": "Eserlekuen ezaugarriak ez du ekitaldi errepikakorrik onartzen. Desgaitu eserlekuen ezaugarria errepikakor egiteko.",
|
||||
"recurring_event_seats_error": "Ekitaldi errepikakorrak ez du eserlekuen ezaugarria onartzen. Desgaitu eserlekuen ezaugarria edo egin ekitaldia ez-errepikakor.",
|
||||
"segment": "Segmentua",
|
||||
"rename": "Berrizendatu",
|
||||
"rename_segment": "Berrizendatu segmentua",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Bertan behera utzitako erreserba gehienak",
|
||||
"name_or_email": "Izena edo helbide elektronikoa",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Kontakturik aurkitzen ez bada, itzuli bezeroen arduradunera existitzen bada",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Gehitu zure kate berriak honen gainean ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Data eta ordua",
|
||||
"email_reminder_upcoming_event_notice" : "Hau zure hurrengo ekitaldiari buruzko abisua da.",
|
||||
"email_reminder_triggered_by_workflow" : "Abisu hau Cal-eko lan-fluxu batek abiarazi zuen.",
|
||||
"enable_delegation_credential": "Gaitu eskuordetze kredentzialak",
|
||||
"enable_delegation_credential_description": "Eman Cal.com-i erakundeko kide guztien egutegietarako sarbide automatikoa eskuordetze kredentzialak gaituz.",
|
||||
"disable_delegation_credential": "Desgaitu eskuordetze kredentzialak",
|
||||
"disable_delegation_credential_description": "Eskuordetze kredentzialak desgaitzen direnean, beren egutegiak konektatu ez dituzten erakundeko kideek eskuz egin beharko dute.",
|
||||
"last_active": "Azken aldiz aktibo",
|
||||
"member_since": "Kide noiztik",
|
||||
"last_updated": "Azken eguneratzea",
|
||||
"salesforce_on_cancel_write_to_event": "Erreserba bertan behera uztean, idatzi gertaera erregistroan gertaera ezabatu beharrean",
|
||||
"salesforce_on_every_cancellation": "Bertan behera uzte bakoitzean",
|
||||
"report_issue": "Arazoa jakinarazi",
|
||||
"report_issue_description": "GitHub-en ticket bat bidali dezakezu edo zure plana eguneratu denbora errealeko laguntza eta garatzaile-konferentziak jasotzeko",
|
||||
"open_issue": "Ireki arazoa",
|
||||
"this_is_your_current_plan": "Hau da zure oraingo plana",
|
||||
"schedule_a_time": "Programatu ordua",
|
||||
"this_includes": "Honek barne hartzen du:",
|
||||
"oauth_client_updated_successfully": "OAuth bezeroa ondo eguneratu da",
|
||||
"oauth_client_not_found": "OAuth bezeroa ez da aurkitu.",
|
||||
"subscribe_to_platform": "Harpidetu plataformara",
|
||||
"error_accessing_webhooks": "Errorea webhook-ak atzitzean.",
|
||||
"webhook_update_failed": "Webhook-a eguneratzeak huts egin du.",
|
||||
"webhook_create_failed": "Webhook-a sortzeak huts egin du.",
|
||||
"invalid_link": "Esteka baliogabea",
|
||||
"currently_subscribed_to_plan": "Une honetan {{planFirstLetter}}{{planRest}} planaren harpideduna zara",
|
||||
"user_team": "Erabiltzailea/Taldea",
|
||||
"client_id_copied": "Bezeroaren IDa kopiatu da!",
|
||||
"client_secret_copied": "Bezeroaren sekretua kopiatu da!",
|
||||
"maintenance_message": "Cal.com taldea programatutako mantentze-lanak egiten ari da. Galderarik baduzu, jarri harremanetan laguntzarekin.",
|
||||
"your_payment_failed": "Zure ordainketak huts egin du",
|
||||
"check_your_inbox": "Begiratu zure sarrera-ontzia",
|
||||
"account_created_premium_not_reserved": "Zure kontua sortu da, baina zure premium ez da erreserbatu.",
|
||||
"email_sent_with_activation_link": "Mezu elektroniko bat bidali dugu {{email}} helbidera zure kontua aktibatzeko esteka batekin.",
|
||||
"activate_account_to_purchase_username": "Behin zure kontua aktibatuta, zure premium erabiltzaile-izena berriro erosten saiatu ahal izango zara edo beste bat hautatu.",
|
||||
"open_in_gmail": "Ireki Gmail-en",
|
||||
"dont_see_email": "Ez duzu mezurik ikusten?",
|
||||
"resend_in_seconds": "Berriz bidali {{seconds}} segundotan",
|
||||
"resend": "Berriz bidali",
|
||||
"verification_email_sent": "Egiaztapen mezua bidali da",
|
||||
"select_all_members": "Hautatu kide guztiak",
|
||||
"select_all_members_tooltip": "Kide guztiak hautatzean, etorkizuneko taldekide guztiak gehituko dira taldera gehitzen direnean.",
|
||||
"form_settings": "Inprimaki ezarpenak",
|
||||
"remove_whitelist_status": "Kendu zerrenda zuriaren egoera",
|
||||
"whitelist_user_workflows": "Zerrenda zurian sartu erabiltzaile-fluxuak",
|
||||
"user_workflows_whitelisted": "Erabiltzaile-fluxuak zerrenda zurian daude",
|
||||
"user_workflows_unwhitelisted": "Erabiltzaile-fluxuak zerrenda zuritik kendu dira",
|
||||
"date_and_time": "Data eta ordua",
|
||||
"email_reminder_upcoming_event_notice": "Hau zure hurrengo ekitaldiari buruzko abisua da.",
|
||||
"email_reminder_triggered_by_workflow": "Abisu hau Cal-eko lan-fluxu batek abiarazi zuen.",
|
||||
"event_upper_case": "Gertaera",
|
||||
"scheduling_by": "Antolatzailea",
|
||||
"experience_review_prompt": "Zein izan da zure azken esperientzia?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Zenbat pozik zaude azken bilerarekin?",
|
||||
"meeting_not_joined_question": "ez zenuen bileran parte hartu?",
|
||||
"reschedule_cta_short": "Berriz programatu hemen.",
|
||||
"hide_organizer_email": "Ezkutatu antolatzailearen helbide elektronikoa",
|
||||
"platform_customer_cant_create_organization": "Dagoeneko plataforma-erakunde bateko kide zarenez, ezin duzu erakunde berri bat sortu. Erabiltzaile bakoitza erakunde bakar batekoa izan daiteke. Mesedez, sortu cal.com kontu berri bat beste helbide elektroniko batekin eta erabili kontu hori erakundeen planera harpidetzeko.",
|
||||
"organization_customer_cant_create_platform": "Dagoeneko erakunde bateko kide zarenez, ezin duzu plataforma-erakunde bat sortu. Erabiltzaile bakoitza erakunde bakar batekoa izan daiteke. Mesedez, sortu cal.com kontu berri bat beste helbide elektroniko batekin eta erabili kontu hori plataforma-planera harpidetzeko.",
|
||||
"hide_organizer_email_description": "Ezkutatu antolatzailearen helbide elektronikoa erreserba pantailatik, mezu elektronikoetatik eta egutegiko ekitaldietatik",
|
||||
"you_and_conjunction": "Zu &",
|
||||
"email_survey_triggered_by_workflow": "Galdeketa hau Cal-eko Workflow baten bidez aktibatu da."
|
||||
"select_verified_email": "Hautatu egiaztatutako helbide elektronikoa",
|
||||
"custom_reply_to_email_title": "'Erantzun' helbide elektroniko pertsonalizatua",
|
||||
"custom_reply_to_email_description": "Erabili beste helbide elektroniko bat baieztapen mezuen erantzun-helbide gisa antolatzailearen helbidearen ordez",
|
||||
"email_survey_triggered_by_workflow": "Galdeketa hau Cal-eko Workflow baten bidez aktibatu da.",
|
||||
"skip_trial": "Saltatu proba aldia",
|
||||
"team_trials_skipped_successfully": "Taldeen probak arrakastaz saltatu dira",
|
||||
"sms_workflow_consent": "Zure telefono zenbakia sartuz, ekitaldi honetarako SMS mezuak jasotzeko baimena ematen duzu. SMS tarifak aplika daitezke.",
|
||||
"routing_preview_more_info_found_insights": "Informazio gehiago <0>Bideratze Estatistiketan</0> aurki daiteke",
|
||||
"results": "Emaitzak",
|
||||
"view_form": "Formularioa Ikusi",
|
||||
"sms_opt_out_message": "Bidali STOP SMS mezuetatik baja emateko",
|
||||
"routing_form_next_in_queue": "{{count}} hurrengo ilaran",
|
||||
"routing_form_select_members_to_email": "Bidali posta elektroniko erantzunak honi",
|
||||
"routing_incomplete_booking_tab": "Osatu gabeko Erreserbak",
|
||||
"include_no_show_in_rr_calculation": "Sartu ez agertzeko erreserbak round robin kalkuluetan",
|
||||
"matching": "Bat egitea",
|
||||
"event_redirect": "Gertaera Birbideratzea",
|
||||
"reset_form": "Formularioa Berrezarri",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Gehitu zure kate berriak honen gainean ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"your_full_name": "Koko nimesi",
|
||||
"no_name": "Ei nimeä",
|
||||
"enter_number_between_range": "Anna numero väliltä 1-{{maxOccurences}}",
|
||||
"continue_as_guest_description": "Nopeaa ja helppoa - tiliä ei tarvita. Täydellinen kertaluontoisiin tapaamisiin.",
|
||||
"email_address": "Sähköpostiosoite",
|
||||
"enter_valid_email": "Anna kelvollinen sähköpostiosoite",
|
||||
"please_schedule_future_call": "Varaa uusi aika, jos emme ole tavoitettavissa {{seconds}} sekunnin kuluessa",
|
||||
@@ -629,6 +630,7 @@
|
||||
"in_person_attendee_address": "Läsnä (osallistujan osoite)",
|
||||
"somewhere_else": "Jossain muualla",
|
||||
"custom_attendee_location": "Mukautettu osallistujan sijainti",
|
||||
"continue_as_guest": "Jatka vieraana",
|
||||
"any_location": "Mikä tahansa sijainti",
|
||||
"yes": "Kyllä",
|
||||
"no": "Ei",
|
||||
@@ -670,9 +672,14 @@
|
||||
"team_updated_successfully": "Tiimi päivitetty onnistuneesti",
|
||||
"your_team_updated_successfully": "Tiimisi on päivitetty onnistuneesti.",
|
||||
"your_org_updated_successfully": "Organisaatiosi on päivitetty onnistuneesti.",
|
||||
"error_copying_to_clipboard": "Virhe kopioitaessa leikepöydälle",
|
||||
"about": "Tietoja",
|
||||
"team_description": "Muutama lause tiimistäsi. Tämä näkyy tiimisi URL-sivulla.",
|
||||
"organization_id": "Organisaation tunnus",
|
||||
"organization_id_copied": "Organisaation tunnus kopioitu.",
|
||||
"org_description": "Muutama lause organisaatiostasi. Tämä näkyy organisaatiosi URL-sivulla.",
|
||||
"team_id": "Tiimin tunnus",
|
||||
"team_id_copied": "Tiimin tunnus kopioitu.",
|
||||
"members": "Jäsenet",
|
||||
"organization_members": "Organisaation jäsenet",
|
||||
"member": "Jäsen",
|
||||
@@ -720,6 +727,9 @@
|
||||
"remove_member_confirmation_message": "Haluatko varmasti poistaa tämän jäsenen tiimistä?",
|
||||
"confirm_disband_team": "Kyllä, hajota tiimi",
|
||||
"confirm_remove_member": "Kyllä, poista jäsen",
|
||||
"confirm_subscription_cancellation": "Kyllä, peruuta tilaus",
|
||||
"cancel_subscription": "Peruuta tilaus",
|
||||
"cancel_subscription_description": "Tilauksen peruuttaminen poistaa nykyisen suunnitelmasi pysyvästi käytöstä. Tätä toimintoa ei voi kumota.",
|
||||
"remove_member": "Poista jäsen",
|
||||
"manage_your_team": "Hallinnoi tiimiäsi",
|
||||
"no_teams": "Sinulla ei ole vielä yhtään tiimiä.",
|
||||
@@ -838,6 +848,7 @@
|
||||
"booking_redirect_uri": "Varaussivusi URL-osoite",
|
||||
"booking_cancel_redirect_uri": "Varauksen peruutussivun URL-osoite",
|
||||
"booking_reschedule_redirect_uri": "Varauksen uudelleenajoitussivun URL-osoite",
|
||||
"booking_conflict_error": "Tämä aika ei ole enää saatavilla. Palaa edelliselle sivulle ja valitse toinen aika.",
|
||||
"open_invitations": "Avoimet kutsut",
|
||||
"new_team": "Uusi tiimi",
|
||||
"create_first_team_and_invite_others": "Luo ensimmäinen tiimisi ja kutsu muita käyttäjiä yhteistyöhön",
|
||||
@@ -1019,6 +1030,8 @@
|
||||
"account_created_with_identity_provider": "Tilisi luotiin käyttäen identiteetintarjoajaa.",
|
||||
"account_managed_by_identity_provider": "Tiliäsi hallinnoi {{provider}}",
|
||||
"account_managed_by_identity_provider_description": "Muuttaaksesi sähköpostiosoitettasi, salasanaasi, ottaaksesi käyttöön kaksivaiheisen tunnistautumisen ja muuta, käy {{provider}}-tilisi asetuksissa.",
|
||||
"account_managed_by_identity_provider_error": "Tiliäsi hallinnoi eri identiteetintarjoaja. Yritä kirjautua sisään palvelulla {{provider}}.",
|
||||
"user_creation_error": "Virhe uuden käyttäjän luomisessa. Yritä uudelleen.",
|
||||
"signin_with_google": "Kirjaudu Google-tilillä",
|
||||
"signin_with_saml": "Kirjaudu SAML-tunnuksilla",
|
||||
"signin_with_saml_oidc": "Kirjaudu SAML/OIDC-tunnuksilla",
|
||||
@@ -1234,6 +1247,7 @@
|
||||
"make_setup_instructions_6": "Kaikki on valmista!",
|
||||
"install_zapier_app": "Asenna ensin Zapier-sovellus sovelluskaupasta",
|
||||
"install_make_app": "Asenna ensin Make-sovellus sovelluskaupasta",
|
||||
"app_installation": "Sovelluksen asennus",
|
||||
"app_not_installed": "Sovellusta ei ole asennettu",
|
||||
"visit_our_app_store": "Pahoittelut, tätä sovellusta ei ole asennettu tilillesi. Tutustu sovelluskauppaamme löytääksesi tämän ja muita hyödyllisiä sovelluksia",
|
||||
"connect_apple_server": "Yhdistä Apple-palvelimeen",
|
||||
@@ -1285,6 +1299,11 @@
|
||||
"event_cancelled_trigger": "kun tapahtuma perutaan",
|
||||
"after_hosts_cal_video_no_show": "Kun järjestäjät eivät liittyneet cal-videoon",
|
||||
"after_guests_cal_video_no_show": "Kun vieraat eivät liittyneet cal-videoon",
|
||||
"join_video_call": "Liity videopuheluun",
|
||||
"sign_in_to_cal_com": "Kirjaudu Cal.com-tilillesi",
|
||||
"log_in_to_cal_com": "Kirjaudu Cal.comiin",
|
||||
"track_your_meetings": "Seuraa tapaamisiasi, saa ilmoituksia ja hallitse aikatauluasi tehokkaammin.",
|
||||
"choose_how_you_d_like_to_join_call": "Valitse, miten haluat liittyä tähän puheluun",
|
||||
"new_event_trigger": "kun uusi tapahtuma varataan",
|
||||
"email_host_action": "lähetä sähköposti järjestäjälle",
|
||||
"email_attendee_action": "lähetä sähköposti osallistujille",
|
||||
@@ -1361,6 +1380,8 @@
|
||||
"custom": "Mukautettu",
|
||||
"reminder": "Muistutus",
|
||||
"rescheduled": "Uudelleenajoitettu",
|
||||
"rescheduled_by": "Uudelleenajoittaja",
|
||||
"original_booking": "Alkuperäinen varaus",
|
||||
"completed": "Valmis",
|
||||
"rating": "Arvostelu",
|
||||
"reminder_email": "Muistutus: {{eventType}} henkilön {{name}} kanssa {{date}}",
|
||||
@@ -1552,7 +1573,9 @@
|
||||
"workflow_turned_on_successfully": "{{workflowName}}-työnkulku {{offOn}} onnistuneesti",
|
||||
"download_responses": "Lataa vastaukset",
|
||||
"download_responses_description": "Lataa kaikki lomakkeen vastaukset CSV-muodossa",
|
||||
"view_responses": "Näytä vastaukset",
|
||||
"download": "Lataa",
|
||||
"downloading": "Ladataan",
|
||||
"download_recording": "Lataa tallenne",
|
||||
"transcription_enabled": "Litterointi on nyt käytössä",
|
||||
"transcription_stopped": "Litterointi on nyt pysäytetty",
|
||||
@@ -1621,6 +1644,7 @@
|
||||
"add_new_team_form": "Lisää uusi lomake tiimillesi",
|
||||
"create_your_first_route": "Luo ensimmäinen reittisi",
|
||||
"route_to_the_right_person": "Ohjaa oikealle henkilölle lomakkeen vastausten perusteella",
|
||||
"form": "Lomake",
|
||||
"form_description": "Luo lomake varaajan ohjaamiseksi",
|
||||
"copy_link_to_form": "Kopioi lomakkeen linkki",
|
||||
"theme": "Varaussivun teema",
|
||||
@@ -1862,6 +1886,8 @@
|
||||
"wrong_code": "Väärä vahvistuskoodi",
|
||||
"not_verified": "Ei vielä vahvistettu",
|
||||
"no_availability_in_month": "Ei vapaita aikoja {{month}}",
|
||||
"no_availability_rolling": "Ajanvaraus on mahdollista vain {{days}} päivää eteenpäin. Tarkista pian uudelleen.",
|
||||
"no_availability_range": "Ajanvaraus päättyi {{date}}. Tarkista pian uudelleen.",
|
||||
"view_previous_month": "Näytä edellinen kuukausi",
|
||||
"view_next_month": "Näytä seuraava kuukausi",
|
||||
"send_code": "Lähetä koodi",
|
||||
@@ -1981,6 +2007,8 @@
|
||||
"booking_with_payment_cancelled": "Tämän tapahtuman maksaminen ei ole enää mahdollista",
|
||||
"booking_with_payment_cancelled_already_paid": "Varauksen maksu palautetaan pian.",
|
||||
"booking_with_payment_cancelled_refunded": "Tämän varauksen maksu on palautettu.",
|
||||
"booking_with_payment_cancelled_no_refund": "Tapahtuman palautuskäytännön mukaisesti varausmaksu ei ole palautettavissa.",
|
||||
"booking_with_payment_cancelled_refund_window_expired": "Tapahtuman palautusaika on umpeutunut. Siksi varausmaksua ei palauteta.",
|
||||
"booking_confirmation_failed": "Varauksen vahvistaminen epäonnistui",
|
||||
"not_enough_seats": "Ei tarpeeksi paikkoja",
|
||||
"form_builder_field_already_exists": "Tämänniminen kenttä on jo olemassa",
|
||||
@@ -2551,6 +2579,8 @@
|
||||
"org_admin_no_slots|cta": "Open users availability",
|
||||
"organization_no_slots_notification_switch_title": "Vastaanota ilmoituksia, kun tiimilläsi ei ole saatavuutta",
|
||||
"organization_no_slots_notification_switch_description": "Ylläpitäjät saavat sähköposti-ilmoituksen, kun käyttäjä yrittää varata tiimin jäsenen aikaa ja kohtaa 'Ei saatavilla' -tilanteen. Lähetämme tämän sähköpostin kahden tapauksen jälkeen ja muistutamme siitä 7 päivän välein per käyttäjä.",
|
||||
"organization_disable_phone_only_sms_notifications_switch_title": "Poista tekstiviesti-ilmoitukset käytöstä vain puhelinnumeroa käyttävissä tapahtumatyypeissä",
|
||||
"organization_disable_phone_only_sms_notifications_switch_description": "Poista käytöstä automaattiset tekstiviesti-ilmoitukset tapahtumatyypeissä, joissa vain puhelinnumero (attendeePhoneNumber) on pakollinen kysymys ja sähköposti on valinnainen tai ei pakollinen",
|
||||
"email_team_invite|subject|added_to_org": "{{user}} added you to the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|invited_to_org": "{{user}} invited you to join the organization {{team}} on {{appName}}",
|
||||
"email_team_invite|subject|added_to_subteam": "{{user}} added you to the team {{team}} of organization {{parentTeamName}} on {{appName}}",
|
||||
@@ -2570,7 +2600,7 @@
|
||||
"email|existing_user_added_link_changed": "Linkkisi on muutettu osoitteesta {{a0}} osoitteeseen {{a1}}, mutta älä huoli, kaikki aiemmat linkit toimivat edelleen ja ohjaavat asianmukaisesti. <br /><br />Huomaa: Kaikki henkilökohtaiset tapahtumatyyppisi on siirretty <strong>{{teamName}}</strong> -organisaatioon, mikä saattaa sisältää myös mahdollisen henkilökohtaisen linkin.<br /><br />Kirjaudu sisään ja varmista, ettei uudella organisaatiotiililläsi ole yksityisiä tapahtumia.<br /><br />Henkilökohtaisia tapahtumia varten suosittelemme luomaan uuden tilin henkilökohtaisella sähköpostiosoitteella.<br /><br />Nauti uudesta selkeästä linkistäsi: {{a2}}",
|
||||
"email_organization_created|subject": "Organisaatiosi on luotu",
|
||||
"your_current_plan": "Nykyinen tilauksesi",
|
||||
"organization_price_per_user_month": "37 $ käyttäjää kohden kuukaudessa (vähintään 30 käyttäjää)",
|
||||
"organization_price_per_user_month": "37 $ käyttäjää kohti kuukaudessa",
|
||||
"privacy_organization_description": "Hallitse organisaatiosi yksityisyysasetuksia",
|
||||
"privacy": "Yksityisyys",
|
||||
"team_will_be_under_org": "Uudet tiimit tulevat olemaan organisaatiosi alla",
|
||||
@@ -2666,6 +2696,8 @@
|
||||
"proceeding_agreement": "Jatkamalla hyväksyt meidän",
|
||||
"terms": "Käyttöehdot",
|
||||
"always_show_x_days": "Aina {{x}} päivää saatavilla",
|
||||
"team_subscription_cancelled_successfully": "Tiimin tilaus peruutettu onnistuneesti",
|
||||
"team_subscription_cancellation_error": "Virhe tiimin tilauksen peruuttamisessa",
|
||||
"unable_to_subscribe_to_the_platform": "Tilausta alustaan ei voitu tehdä, yritä myöhemmin uudelleen",
|
||||
"updating_oauth_client_error": "OAuth-asiakkaan päivityksessä tapahtui virhe, yritä myöhemmin uudelleen",
|
||||
"creating_oauth_client_error": "OAuth-asiakkaan luonnissa tapahtui virhe, yritä myöhemmin uudelleen",
|
||||
@@ -2769,6 +2801,7 @@
|
||||
"salesforce_skip_entry_creation": "Ohita {{entry}}-tietueen luominen, jos sitä ei ole Salesforcessa",
|
||||
"salesforce_if_account_does_not_exist": "Jos yhteyshenkilöä ei ole tilin alla, luo uusi liidi osallistujasta",
|
||||
"salesforce_create_new_contact_under_account": "Luo uusi yhteyshenkilö tilin alle osallistujan sähköpostin domainin ja olemassa olevien yhteyshenkilöiden perusteella",
|
||||
"salesforce_change_record_owner_on_booking": "Vaihda tietueen omistaja varauksessa",
|
||||
"mass_assign_attributes": "Määritä ominaisuudet massana",
|
||||
"reroute_preview_custom_message": "Tämä näyttää mukautetun viestin. Kokeile muuttaa vastaus reitittämään tapahtumaan",
|
||||
"reroute_preview_external_redirect": "Tämä uudelleenohjaa osoitteeseen {{externalUrl}}. Kokeile muuttaa vastaus reitittämään tapahtumaan",
|
||||
@@ -2861,10 +2894,11 @@
|
||||
"routed_to_per_period": "Reititetty kohteeseen ajanjaksolla",
|
||||
"per_day": "Päivittäin",
|
||||
"per_week": "Viikoittain",
|
||||
"per_month": "Kuukausittain",
|
||||
"per_month": "kuukaudessa",
|
||||
"routing_form_insights_assignment_reason": "Kohdistamisen syy",
|
||||
"access_denied": "Pääsy estetty",
|
||||
"salesforce_route_to_owner": "Yhteyshenkilön omistajasta tulee Round Robin -isäntä, jos mahdollista",
|
||||
"salesforce_add_attendees_as": "Lisää uudet osallistujat nimellä",
|
||||
"salesforce_do_not_route_to_owner": "Yhteyshenkilön omistajaa ei pakoteta (voi silti olla isäntä, jos vastaa määritettyjä ominaisuuksia ja Round Robin -kriteerejä)",
|
||||
"salesforce_route_to_custom_lookup_field": "Reititä käyttäjälle, joka vastaa tilin hakukenttää",
|
||||
"salesforce_option": "Salesforce-asetus",
|
||||
@@ -2927,6 +2961,7 @@
|
||||
"shortfall": "Vajaus",
|
||||
"routing_form": "Reitityskaavake",
|
||||
"go_back_and_save": "Palaa takaisin ja tallenna",
|
||||
"save_changes": "Tallenna muutokset",
|
||||
"leave_without_saving": "Poistu tallentamatta",
|
||||
"leave_without_saving_description": "Haluatko varmasti poistua tallentamatta muutoksia reitityslomaakkeeseesi?",
|
||||
"something_unexpected_occurred": "Jotain odottamatonta tapahtui",
|
||||
@@ -2961,6 +2996,9 @@
|
||||
"authorize": "Valtuuta",
|
||||
"next": "Seuraava",
|
||||
"hide": "Piilota",
|
||||
"show": "Näytä",
|
||||
"utm_params": "UTM-parametrit",
|
||||
"no_utm_params": "UTM-parametreja ei ole saatavilla.",
|
||||
"asc": "Nouseva",
|
||||
"desc": "Laskeva",
|
||||
"verify_email_change": "Vahvista sähköpostin muutos",
|
||||
@@ -2972,6 +3010,7 @@
|
||||
"you_need_to_have_minimum_published_teams": "Sinulla täytyy olla vähimmäismäärä julkaistuja tiimejä",
|
||||
"you_are_part_of_this_organization_already": "Olet jo osa tätä organisaatiota",
|
||||
"you_are_part_of_another_organization_cannot_create_organization": "Olet osa toista organisaatiota, et voi luoda uutta organisaatiota",
|
||||
"you_are_part_of_another_platform_organization_cannot_create_organization": "Olet osa toista alustaorganisaatiota, et voi luoda uutta organisaatiota",
|
||||
"organization_payment_success": "Organisaation maksu onnistui",
|
||||
"organization_payment_success_description": "Organisaatiosi on luotu onnistuneesti",
|
||||
"this_may_take_a_few_seconds": "Tämä saattaa kestää muutaman sekunnin...",
|
||||
@@ -2983,7 +3022,7 @@
|
||||
"organization_onboarding_already_completed": "Organisaation perehdytys on jo suoritettu",
|
||||
"organization_onboarding_already_exists": "Organisaation perehdytys on jo olemassa",
|
||||
"organization_onboarding_not_found": "Organisaation perehdytystä ei löydy",
|
||||
"payment_successful": "Maksu onnistui",
|
||||
"payment_successful": "Maksu onnistui!",
|
||||
"handover_onboarding_page_title": "Perehdytyksen luovutus",
|
||||
"handover_onboarding_page_description": "Perehdytyksen luovutus käyttäjälle",
|
||||
"organization_already_exists_with_this_slug": "Organisaatio on jo olemassa tällä verkko-osoitteella",
|
||||
@@ -3022,6 +3061,9 @@
|
||||
"tip_username_plus": "Vinkki: Voit lisätä '+'-merkin käyttäjänimien väliin: cal.com/anna+brian luodaksesi dynaamisen ryhmätapaamisen",
|
||||
"user_has_no_team_yet": "Sinulla ei ole vielä tiimiä",
|
||||
"no_team_members": "Sinulla ei ole vielä tiimin jäseniä",
|
||||
"recurring_event_doesnt_support_seats": "Toistuva tapahtuma ei tue paikkaominaisuutta. Tee siitä ei-toistuva ottaaksesi paikat käyttöön.",
|
||||
"seats_doesnt_support_recurring": "Paikkaominaisuus ei tue toistuvaa tapahtumaa. Poista paikkaominaisuus käytöstä tehdäksesi siitä toistuvan.",
|
||||
"recurring_event_seats_error": "Toistuva tapahtuma ei tue paikkaominaisuutta. Poista paikkaominaisuus käytöstä tai tee tapahtumasta ei-toistuva.",
|
||||
"segment": "Segmentti",
|
||||
"rename": "Nimeä uudelleen",
|
||||
"rename_segment": "Nimeä segmentti uudelleen",
|
||||
@@ -3053,10 +3095,53 @@
|
||||
"most_cancelled_bookings": "Eniten perutut varaukset",
|
||||
"name_or_email": "Nimi tai sähköposti",
|
||||
"salesforce_round_robin_skip_fallback_to_lead_owner": "Jos yhteyshenkilöä ei löydy, käytä liidin omistajaa, jos sellainen on olemassa",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Lisää uudet merkkijonot tämän yläpuolelle ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
|
||||
"date_and_time" : "Päivämäärä ja aika",
|
||||
"email_reminder_upcoming_event_notice" : "Tämä on muistutus tulevasta tapahtumastasi.",
|
||||
"email_reminder_triggered_by_workflow" : "Tämän muistutuksen laukaisi Cal.",
|
||||
"enable_delegation_credential": "Ota delegointitunniste käyttöön",
|
||||
"enable_delegation_credential_description": "Myönnä Cal.comille automaattinen pääsy kaikkien organisaation jäsenten kalentereihin ottamalla delegointitunniste käyttöön.",
|
||||
"disable_delegation_credential": "Poista delegointitunniste käytöstä",
|
||||
"disable_delegation_credential_description": "Kun delegointitunniste on poistettu käytöstä, organisaation jäsenten, jotka eivät ole yhdistäneet kalentereitaan, on tehtävä se manuaalisesti.",
|
||||
"last_active": "Viimeksi aktiivinen",
|
||||
"member_since": "Jäsen alkaen",
|
||||
"last_updated": "Viimeksi päivitetty",
|
||||
"salesforce_on_cancel_write_to_event": "Peruutetun varauksen yhteydessä kirjoita tapahtuman tietueeseen tapahtuman poistamisen sijaan",
|
||||
"salesforce_on_every_cancellation": "Jokaisessa peruutuksessa",
|
||||
"report_issue": "Ilmoita ongelmasta",
|
||||
"report_issue_description": "Voit lähettää tukipyynnön GitHubissa tai päivittää tilauksesi saadaksesi reaaliaikaista tukea kehittäjäkonferenssien kanssa",
|
||||
"open_issue": "Avaa ongelma",
|
||||
"this_is_your_current_plan": "Tämä on nykyinen tilauksesi",
|
||||
"schedule_a_time": "Varaa aika",
|
||||
"this_includes": "Tämä sisältää:",
|
||||
"oauth_client_updated_successfully": "OAuth-asiakas päivitetty onnistuneesti",
|
||||
"oauth_client_not_found": "OAuth-asiakasta ei löytynyt.",
|
||||
"subscribe_to_platform": "Tilaa alusta",
|
||||
"error_accessing_webhooks": "Virhe webhookien käytössä.",
|
||||
"webhook_update_failed": "Webhookin päivitys epäonnistui.",
|
||||
"webhook_create_failed": "Webhookin luonti epäonnistui.",
|
||||
"invalid_link": "Virheellinen linkki",
|
||||
"currently_subscribed_to_plan": "Olet tällä hetkellä tilannut {{planFirstLetter}}{{planRest}}-tilauksen",
|
||||
"user_team": "Käyttäjä/Tiimi",
|
||||
"client_id_copied": "Asiakas-ID kopioitu!",
|
||||
"client_secret_copied": "Asiakassalaisuus kopioitu!",
|
||||
"maintenance_message": "Cal.com-tiimi suorittaa suunniteltua huoltoa. Jos sinulla on kysyttävää, ota yhteyttä tukeen.",
|
||||
"your_payment_failed": "Maksusi epäonnistui",
|
||||
"check_your_inbox": "Tarkista saapuneet viestisi",
|
||||
"account_created_premium_not_reserved": "Tilisi on luotu, mutta premium-käyttäjänimeä ei ole varattu.",
|
||||
"email_sent_with_activation_link": "Olemme lähettäneet sähköpostin osoitteeseen {{email}} linkillä tilisi aktivoimiseksi.",
|
||||
"activate_account_to_purchase_username": "Kun aktivoit tilisi, voit yrittää ostaa premium-käyttäjänimesi uudelleen tai valita toisen.",
|
||||
"open_in_gmail": "Avaa Gmailissa",
|
||||
"dont_see_email": "Etkö näe sähköpostia?",
|
||||
"resend_in_seconds": "Lähetä uudelleen {{seconds}} sekunnin kuluttua",
|
||||
"resend": "Lähetä uudelleen",
|
||||
"verification_email_sent": "Vahvistussähköposti lähetetty",
|
||||
"select_all_members": "Valitse kaikki jäsenet",
|
||||
"select_all_members_tooltip": "Kaikkien jäsenten valinta lisää myös kaikki tulevat tiimin jäsenet, kun heidät lisätään tiimiin.",
|
||||
"form_settings": "Lomakkeen asetukset",
|
||||
"remove_whitelist_status": "Poista sallittujen listalta",
|
||||
"whitelist_user_workflows": "Lisää käyttäjän työnkulut sallittujen listalle",
|
||||
"user_workflows_whitelisted": "Käyttäjän työnkulut lisätty sallittujen listalle",
|
||||
"user_workflows_unwhitelisted": "Käyttäjän työnkulut poistettu sallittujen listalta",
|
||||
"date_and_time": "Päivämäärä ja aika",
|
||||
"email_reminder_upcoming_event_notice": "Tämä on muistutus tulevasta tapahtumastasi.",
|
||||
"email_reminder_triggered_by_workflow": "Tämän muistutuksen laukaisi Cal.",
|
||||
"event_upper_case": "Tapahtuma",
|
||||
"scheduling_by": "Aikatauluttaja",
|
||||
"experience_review_prompt": "Minkälainen oli viimeisin kokemuksesi?",
|
||||
@@ -3064,6 +3149,28 @@
|
||||
"meeting_satisfaction_question": "Kuinka tyytyväinen olit viime kokoukseen?",
|
||||
"meeting_not_joined_question": "et osallistunut kokoukseen?",
|
||||
"reschedule_cta_short": "Uudelleenaikatauluta tästä.",
|
||||
"hide_organizer_email": "Piilota järjestäjän sähköposti",
|
||||
"platform_customer_cant_create_organization": "Olet jo osa alusta-organisaatiota, minkä vuoksi et voi luoda uutta organisaatiota. Jokainen käyttäjä voi kuulua vain yhteen organisaatioon. Luo uusi cal.com-tili eri sähköpostiosoitteella ja käytä sitä tiliä organisaatiosuunnitelman tilaamiseen.",
|
||||
"organization_customer_cant_create_platform": "Olet jo osa organisaatiota, minkä vuoksi et voi luoda alusta-organisaatiota. Jokainen käyttäjä voi kuulua vain yhteen organisaatioon. Luo uusi cal.com-tili eri sähköpostiosoitteella ja käytä sitä tiliä alustasuunnitelman tilaamiseen.",
|
||||
"hide_organizer_email_description": "Piilota järjestäjän sähköpostiosoite varausnäytöltä, sähköposti-ilmoituksista ja kalenteritapahtumista",
|
||||
"you_and_conjunction": "Sinä &",
|
||||
"email_survey_triggered_by_workflow": "Tämä kysely käynnistettiin Workflow-ohjelmalla Cal-palvelussa."
|
||||
"select_verified_email": "Valitse vahvistettu sähköposti",
|
||||
"custom_reply_to_email_title": "Mukautettu 'Vastaa'-sähköposti",
|
||||
"custom_reply_to_email_description": "Käytä eri sähköpostiosoitetta vastausosoitteena vahvistussähköposteissa järjestäjän sähköpostin sijaan",
|
||||
"email_survey_triggered_by_workflow": "Tämä kysely käynnistettiin Workflow-ohjelmalla Cal-palvelussa.",
|
||||
"skip_trial": "Ohita kokeilujakso",
|
||||
"team_trials_skipped_successfully": "Tiimin kokeilujaksot ohitettu onnistuneesti",
|
||||
"sms_workflow_consent": "Antamalla puhelinnumerosi suostut vastaanottamaan tekstiviestejä tästä tapahtumasta. Tekstiviesteistä voidaan veloittaa operaattorin mukainen maksu.",
|
||||
"routing_preview_more_info_found_insights": "Lisätietoja löytyy <0>Reitityksen tiedoista</0>",
|
||||
"results": "Tulokset",
|
||||
"view_form": "Näytä lomake",
|
||||
"sms_opt_out_message": "Lähetä STOP peruuttaaksesi SMS-viestit",
|
||||
"routing_form_next_in_queue": "{{count}} seuraavana jonossa",
|
||||
"routing_form_select_members_to_email": "Lähetä sähköpostivastaukset henkilöille",
|
||||
"routing_incomplete_booking_tab": "Keskeneräiset varaukset",
|
||||
"include_no_show_in_rr_calculation": "Sisällytä no-show-varaukset round robin -laskelmiin",
|
||||
"matching": "Vastaavuus",
|
||||
"event_redirect": "Tapahtuman uudelleenohjaus",
|
||||
"reset_form": "Nollaa lomake",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Lisää uudet merkkijonot tämän yläpuolelle ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user