Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79a8ab79f8 | ||
|
|
ce87de4fc7 | ||
|
|
b128579729 | ||
|
|
3cc5d9c065 | ||
|
|
7897e14273 | ||
|
|
c581456586 | ||
|
|
36dd3e9e6c | ||
|
|
f137aee436 | ||
|
|
4f494d5a32 | ||
|
|
cce6e83578 | ||
|
|
c21ba636d2 | ||
|
|
5ccf5e6be8 | ||
|
|
66b3e735d8 | ||
|
|
7a8b9ededb | ||
|
|
501c49f369 | ||
|
|
536604455b | ||
|
|
cfb76a9689 | ||
|
|
30180edc0b | ||
|
|
2aa3d1d4e0 | ||
|
|
21694c039a | ||
|
|
a8c29b5459 | ||
|
|
6cd7454f43 | ||
|
|
99b2419dd7 | ||
|
|
f6d0a2ca09 | ||
|
|
f5ab9bd40b | ||
|
|
07085b9ffb | ||
|
|
14151b827f | ||
|
|
28b757f19c | ||
|
|
68455db860 | ||
|
|
96ff88d266 | ||
|
|
f88a91dad0 | ||
|
|
35059d7727 | ||
|
|
68f76e2acc | ||
|
|
80aac06ff3 | ||
|
|
0f47528ba2 | ||
|
|
113dc5fca6 | ||
|
|
0befdde5d7 | ||
|
|
b3ed6e39e3 | ||
|
|
e07b1eda32 | ||
|
|
8262894bde | ||
|
|
a3d7bcd22e | ||
|
|
62b753afba | ||
|
|
bb40b2f6bf | ||
|
|
f628dc83a8 | ||
|
|
2fd2578504 | ||
|
|
a29407349d | ||
|
|
e7df1ef493 | ||
|
|
b652ae7714 | ||
|
|
cec1c9ee46 |
@@ -12,16 +12,6 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/dangerous-git-checkout
|
||||
- uses: ./.github/actions/yarn-install
|
||||
- name: Run Linting with Reports
|
||||
run: yarn lint:report
|
||||
- name: Run Lint
|
||||
run: yarn lint
|
||||
continue-on-error: true
|
||||
|
||||
- name: Merge lint reports
|
||||
run: jq -s '[.[]]|flatten' lint-results/*.json &> lint-results/eslint_report.json
|
||||
|
||||
- name: Upload ESLint report
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: lint-results
|
||||
path: lint-results
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
undecided:
|
||||
- "@calcom/app-store-cli"
|
||||
- "@calcom/platform-constants"
|
||||
- "@calcom/platform-enums"
|
||||
- "@calcom/platform-types"
|
||||
- "@calcom/platform-utils"
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
undecided:
|
||||
- calcom-monorepo
|
||||
- "@calcom/app-store-cli"
|
||||
- "@calcom/platform-constants"
|
||||
- "@calcom/platform-enums"
|
||||
- "@calcom/platform-types"
|
||||
- "@calcom/platform-utils"
|
||||
- "@calcom/prisma"
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
undecided:
|
||||
- calcom-monorepo
|
||||
- "@calcom/prisma"
|
||||
@@ -29,7 +29,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.81",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.82",
|
||||
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from "@nestjs/swagger";
|
||||
import { Transform } from "class-transformer";
|
||||
import { IsDate, IsInt, IsOptional, IsString, IsEnum, isDate } from "class-validator";
|
||||
|
||||
import { SkipTakePagination } from "@calcom/platform-types";
|
||||
|
||||
export enum OutOfOfficeReason {
|
||||
UNSPECIFIED = "unspecified",
|
||||
VACATION = "vacation",
|
||||
@@ -80,3 +82,47 @@ export class CreateOutOfOfficeEntryDto {
|
||||
}
|
||||
|
||||
export class UpdateOutOfOfficeEntryDto extends PartialType(CreateOutOfOfficeEntryDto) {}
|
||||
|
||||
export enum SortOrder {
|
||||
asc = "asc",
|
||||
desc = "desc",
|
||||
}
|
||||
type SortOrderType = keyof typeof SortOrder;
|
||||
|
||||
export class GetOutOfOfficeEntryFiltersDTO extends SkipTakePagination {
|
||||
@IsOptional()
|
||||
@IsEnum(SortOrder, {
|
||||
message: 'SortStart must be either "asc" or "desc".',
|
||||
})
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description: "Sort results by their start time in ascending or descending order.",
|
||||
example: "?sortStart=asc OR ?sortStart=desc",
|
||||
enum: SortOrder,
|
||||
})
|
||||
sortStart?: SortOrderType;
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(SortOrder, {
|
||||
message: 'SortEnd must be either "asc" or "desc".',
|
||||
})
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description: "Sort results by their end time in ascending or descending order.",
|
||||
example: "?sortEnd=asc OR ?sortEnd=desc",
|
||||
enum: SortOrder,
|
||||
})
|
||||
sortEnd?: SortOrderType;
|
||||
}
|
||||
|
||||
export class GetOrgUsersOutOfOfficeEntryFiltersDTO extends GetOutOfOfficeEntryFiltersDTO {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@ApiProperty({
|
||||
type: String,
|
||||
required: false,
|
||||
description: "Filter ooo entries by the user email address. user must be within your organization.",
|
||||
example: "example@domain.com",
|
||||
})
|
||||
email?: string;
|
||||
}
|
||||
|
||||
@@ -46,12 +46,19 @@ export class UserOOORepository {
|
||||
});
|
||||
}
|
||||
|
||||
async getUserOOOPaginated(userId: number, skip: number, take: number) {
|
||||
async getUserOOOPaginated(
|
||||
userId: number,
|
||||
skip: number,
|
||||
take: number,
|
||||
sort?: { sortStart?: "asc" | "desc"; sortEnd?: "asc" | "desc" }
|
||||
) {
|
||||
return this.dbRead.prisma.outOfOfficeEntry.findMany({
|
||||
where: { userId },
|
||||
skip,
|
||||
take,
|
||||
include: { reason: true },
|
||||
...(sort?.sortStart && { orderBy: { start: sort.sortStart } }),
|
||||
...(sort?.sortEnd && { orderBy: { end: sort.sortEnd } }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import {
|
||||
CreateOutOfOfficeEntryDto,
|
||||
UpdateOutOfOfficeEntryDto,
|
||||
OutOfOfficeReason,
|
||||
GetOutOfOfficeEntryFiltersDTO,
|
||||
SortOrder,
|
||||
} from "@/modules/ooo/inputs/ooo.input";
|
||||
import { UserOOORepository } from "@/modules/ooo/repositories/ooo.repository";
|
||||
import { UsersRepository } from "@/modules/users/users.repository";
|
||||
@@ -128,8 +130,13 @@ export class UserOOOService {
|
||||
return this.formatOooReason(ooo);
|
||||
}
|
||||
|
||||
async getUserOOOPaginated(userId: number, skip: number, take: number) {
|
||||
const ooos = await this.oooRepository.getUserOOOPaginated(userId, skip, take);
|
||||
async getUserOOOPaginated(
|
||||
userId: number,
|
||||
skip: number,
|
||||
take: number,
|
||||
sort?: { sortStart?: "asc" | "desc"; sortEnd?: "asc" | "desc" }
|
||||
) {
|
||||
const ooos = await this.oooRepository.getUserOOOPaginated(userId, skip, take, sort);
|
||||
return ooos.map((ooo) => this.formatOooReason(ooo));
|
||||
}
|
||||
}
|
||||
|
||||
+38
-10
@@ -8,13 +8,19 @@ import { IsOrgGuard } from "@/modules/auth/guards/organizations/is-org.guard";
|
||||
import { RolesGuard } from "@/modules/auth/guards/roles/roles.guard";
|
||||
import { IsUserInOrg } from "@/modules/auth/guards/users/is-user-in-org.guard";
|
||||
import { IsUserOOO } from "@/modules/ooo/guards/is-user-ooo";
|
||||
import { CreateOutOfOfficeEntryDto, UpdateOutOfOfficeEntryDto } from "@/modules/ooo/inputs/ooo.input";
|
||||
import {
|
||||
CreateOutOfOfficeEntryDto,
|
||||
UpdateOutOfOfficeEntryDto,
|
||||
GetOutOfOfficeEntryFiltersDTO,
|
||||
GetOrgUsersOutOfOfficeEntryFiltersDTO,
|
||||
} from "@/modules/ooo/inputs/ooo.input";
|
||||
import {
|
||||
UserOooOutputDto,
|
||||
UserOooOutputResponseDto,
|
||||
UserOoosOutputResponseDto,
|
||||
} from "@/modules/ooo/outputs/ooo.output";
|
||||
import { UserOOOService } from "@/modules/ooo/services/ooo.service";
|
||||
import { OrgUsersOOOService } from "@/modules/organizations/controllers/users/ooo/services/organization-users-ooo.service";
|
||||
import {
|
||||
Controller,
|
||||
UseGuards,
|
||||
@@ -33,10 +39,9 @@ import { ApiOperation, ApiTags as DocsTags } from "@nestjs/swagger";
|
||||
import { plainToInstance } from "class-transformer";
|
||||
|
||||
import { SUCCESS_STATUS } from "@calcom/platform-constants";
|
||||
import { SkipTakePagination } from "@calcom/platform-types";
|
||||
|
||||
@Controller({
|
||||
path: "/v2/organizations/:orgId/users/:userId/ooo",
|
||||
path: "/v2/organizations/:orgId",
|
||||
version: API_VERSIONS_VALUES,
|
||||
})
|
||||
@UseInterceptors(ClassSerializerInterceptor)
|
||||
@@ -44,18 +49,22 @@ import { SkipTakePagination } from "@calcom/platform-types";
|
||||
@UseGuards(IsOrgGuard)
|
||||
@DocsTags("Orgs / Users / OOO")
|
||||
export class OrganizationsUsersOOOController {
|
||||
constructor(private readonly userOOOService: UserOOOService) {}
|
||||
constructor(
|
||||
private readonly userOOOService: UserOOOService,
|
||||
private readonly orgUsersOOOService: OrgUsersOOOService
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@Get("/users/:userId/ooo")
|
||||
@Roles("ORG_ADMIN")
|
||||
@PlatformPlan("ESSENTIALS")
|
||||
@UseGuards(IsUserInOrg)
|
||||
@ApiOperation({ summary: "Get all ooo entries of a user" })
|
||||
async getOrganizationUserOOO(
|
||||
@Param("userId", ParseIntPipe) userId: number,
|
||||
@Query() query: SkipTakePagination
|
||||
@Query() query: GetOutOfOfficeEntryFiltersDTO
|
||||
): Promise<UserOoosOutputResponseDto> {
|
||||
const ooos = await this.userOOOService.getUserOOOPaginated(userId, query.skip ?? 0, query.take ?? 250);
|
||||
const { skip, take, ...rest } = query ?? { skip: 0, take: 250 };
|
||||
const ooos = await this.userOOOService.getUserOOOPaginated(userId, skip ?? 0, take ?? 250, rest);
|
||||
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
@@ -63,7 +72,7 @@ export class OrganizationsUsersOOOController {
|
||||
};
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Post("/users/:userId/ooo")
|
||||
@Roles("ORG_ADMIN")
|
||||
@PlatformPlan("ESSENTIALS")
|
||||
@UseGuards(IsUserInOrg)
|
||||
@@ -79,7 +88,7 @@ export class OrganizationsUsersOOOController {
|
||||
};
|
||||
}
|
||||
|
||||
@Patch("/:oooId")
|
||||
@Patch("/users/:userId/ooo/:oooId")
|
||||
@Roles("ORG_ADMIN")
|
||||
@PlatformPlan("ESSENTIALS")
|
||||
@UseGuards(IsUserInOrg, IsUserOOO)
|
||||
@@ -97,7 +106,7 @@ export class OrganizationsUsersOOOController {
|
||||
};
|
||||
}
|
||||
|
||||
@Delete("/:oooId")
|
||||
@Delete("/users/:userId/ooo/:oooId")
|
||||
@Roles("ORG_ADMIN")
|
||||
@PlatformPlan("ESSENTIALS")
|
||||
@UseGuards(IsUserInOrg, IsUserOOO)
|
||||
@@ -111,4 +120,23 @@ export class OrganizationsUsersOOOController {
|
||||
data: plainToInstance(UserOooOutputDto, ooo, { strategy: "excludeAll" }),
|
||||
};
|
||||
}
|
||||
|
||||
@Get("/ooo")
|
||||
@Roles("ORG_ADMIN")
|
||||
@PlatformPlan("ESSENTIALS")
|
||||
@ApiOperation({ summary: "Get all OOO entries of org users" })
|
||||
async getOrganizationUsersOOO(
|
||||
@Param("orgId", ParseIntPipe) orgId: number,
|
||||
@Query() query: GetOrgUsersOutOfOfficeEntryFiltersDTO
|
||||
): Promise<UserOoosOutputResponseDto> {
|
||||
const { skip, take, email, ...rest } = query ?? { skip: 0, take: 250 };
|
||||
const ooos = await this.orgUsersOOOService.getOrgUsersOOOPaginated(orgId, skip ?? 0, take ?? 250, rest, {
|
||||
email,
|
||||
});
|
||||
|
||||
return {
|
||||
status: SUCCESS_STATUS,
|
||||
data: ooos.map((ooo) => plainToInstance(UserOooOutputDto, ooo, { strategy: "excludeAll" })),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -366,6 +366,31 @@ describe("Organizations User OOO Endpoints", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should get 2 ooo entries", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/organizations/${org.id}/ooo?sortEnd=desc&email=${teammate1Email}`)
|
||||
.expect(200)
|
||||
.then((response) => {
|
||||
const responseBody = response.body;
|
||||
expect(responseBody.status).toEqual(SUCCESS_STATUS);
|
||||
|
||||
const data = responseBody.data as UserOooOutputDto[];
|
||||
expect(data.length).toEqual(2);
|
||||
const oooUno = data.find((ooo) => ooo.id === oooCreatedViaApiId);
|
||||
expect(oooUno).toBeDefined();
|
||||
if (oooUno) {
|
||||
expect(oooUno.reason).toEqual("vacation");
|
||||
expect(oooUno.toUserId).toEqual(teammate2.id);
|
||||
expect(oooUno.userId).toEqual(teammate1.id);
|
||||
expect(oooUno.start).toEqual("2025-06-01T00:00:00.000Z");
|
||||
expect(oooUno.end).toEqual("2025-06-10T23:59:59.999Z");
|
||||
}
|
||||
// test sort
|
||||
expect(data[1].id).toEqual(oooCreatedViaApiId);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it("should get 2 ooo entries", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/organizations/${org.id}/users/${teammate1.id}/ooo`)
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class OrgUsersOOORepository {
|
||||
constructor(private readonly dbRead: PrismaReadService) {}
|
||||
async getOrgUsersOOOPaginated(
|
||||
orgId: number,
|
||||
skip: number,
|
||||
take: number,
|
||||
sort?: { sortStart?: "asc" | "desc"; sortEnd?: "asc" | "desc" },
|
||||
filters?: { email?: string }
|
||||
) {
|
||||
console.log({ sort, filters });
|
||||
return this.dbRead.prisma.outOfOfficeEntry.findMany({
|
||||
where: {
|
||||
user: {
|
||||
...(filters?.email && { email: filters.email }),
|
||||
profiles: {
|
||||
some: {
|
||||
organizationId: orgId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
skip,
|
||||
take,
|
||||
include: { reason: true },
|
||||
...(sort?.sortStart && { orderBy: { start: sort.sortStart } }),
|
||||
...(sort?.sortEnd && { orderBy: { end: sort.sortEnd } }),
|
||||
});
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { UserOOORepository } from "@/modules/ooo/repositories/ooo.repository";
|
||||
import { UserOOOService } from "@/modules/ooo/services/ooo.service";
|
||||
import { OrgUsersOOORepository } from "@/modules/organizations/controllers/users/ooo/repositories/organizations-users-ooo.repository";
|
||||
import { UsersRepository } from "@/modules/users/users.repository";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class OrgUsersOOOService {
|
||||
constructor(
|
||||
private readonly oooRepository: UserOOORepository,
|
||||
private readonly oooUserService: UserOOOService,
|
||||
private readonly usersRepository: UsersRepository,
|
||||
private readonly orgUsersOOORepository: OrgUsersOOORepository
|
||||
) {}
|
||||
|
||||
async getOrgUsersOOOPaginated(
|
||||
orgId: number,
|
||||
skip: number,
|
||||
take: number,
|
||||
sort?: { sortStart?: "asc" | "desc"; sortEnd?: "asc" | "desc" },
|
||||
filters?: { email?: string }
|
||||
) {
|
||||
const ooos = await this.orgUsersOOORepository.getOrgUsersOOOPaginated(orgId, skip, take, sort, filters);
|
||||
return ooos.map((ooo) => this.oooUserService.formatOooReason(ooo));
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import { OrganizationsTeamsMembershipsController } from "@/modules/organizations
|
||||
import { OrganizationsTeamsController } from "@/modules/organizations/controllers/teams/organizations-teams.controller";
|
||||
import { OrganizationsTeamsSchedulesController } from "@/modules/organizations/controllers/teams/schedules/organizations-teams-schedules.controller";
|
||||
import { OrganizationsUsersOOOController } from "@/modules/organizations/controllers/users/ooo/organizations-users-ooo-controller";
|
||||
import { OrgUsersOOORepository } from "@/modules/organizations/controllers/users/ooo/repositories/organizations-users-ooo.repository";
|
||||
import { OrgUsersOOOService } from "@/modules/organizations/controllers/users/ooo/services/organization-users-ooo.service";
|
||||
import { OrganizationsUsersController } from "@/modules/organizations/controllers/users/organizations-users.controller";
|
||||
import { OrganizationsWebhooksController } from "@/modules/organizations/controllers/webhooks/organizations-webhooks.controller";
|
||||
import { OrganizationsRepository } from "@/modules/organizations/organizations.repository";
|
||||
@@ -91,6 +93,8 @@ import { Module } from "@nestjs/common";
|
||||
OutputTeamEventTypesResponsePipe,
|
||||
UserOOOService,
|
||||
UserOOORepository,
|
||||
OrgUsersOOOService,
|
||||
OrgUsersOOORepository,
|
||||
],
|
||||
exports: [
|
||||
OrganizationsService,
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
||||
import { Transform } from "class-transformer";
|
||||
import { IsOptional, Validate } from "class-validator";
|
||||
|
||||
import { SkipTakePagination } from "@calcom/platform-types";
|
||||
import { IsNumber, IsOptional, Max, Min, Validate } from "class-validator";
|
||||
|
||||
import { IsEmailStringOrArray } from "../validators/isEmailStringOrArray";
|
||||
|
||||
export class GetUsersInput extends SkipTakePagination {
|
||||
export class GetUsersInput {
|
||||
@ApiProperty({ required: false, description: "The number of items to return", example: 10 })
|
||||
@Transform(({ value }: { value: string }) => value && parseInt(value))
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@Max(1000)
|
||||
@IsOptional()
|
||||
take?: number;
|
||||
|
||||
@ApiProperty({ required: false, description: "The number of items to skip", example: 0 })
|
||||
@Transform(({ value }: { value: string }) => value && parseInt(value))
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@IsOptional()
|
||||
skip?: number;
|
||||
|
||||
@IsOptional()
|
||||
@Validate(IsEmailStringOrArray)
|
||||
@Transform(({ value }: { value: string | string[] }) => {
|
||||
|
||||
@@ -2516,6 +2516,8 @@
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"minimum": 1,
|
||||
"maximum": 1000,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -2526,6 +2528,7 @@
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -2716,6 +2719,34 @@
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their start time in ascending or descending order.",
|
||||
"example": "?sortStart=asc OR ?sortStart=desc",
|
||||
"schema": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortEnd",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their end time in ascending or descending order.",
|
||||
"example": "?sortEnd=asc OR ?sortEnd=desc",
|
||||
"schema": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -2824,6 +2855,88 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/organizations/{orgId}/ooo": {
|
||||
"get": {
|
||||
"operationId": "OrganizationsUsersOOOController_getOrganizationUsersOOO",
|
||||
"summary": "Get all OOO entries of org users",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "orgId",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "skip",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their start time in ascending or descending order.",
|
||||
"example": "?sortStart=asc OR ?sortStart=desc",
|
||||
"schema": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortEnd",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their end time in ascending or descending order.",
|
||||
"example": "?sortEnd=asc OR ?sortEnd=desc",
|
||||
"schema": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter ooo entries by the user email address. user must be within your organization.",
|
||||
"example": "example@domain.com",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Orgs / Users / OOO"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/organizations/{orgId}/webhooks": {
|
||||
"get": {
|
||||
"operationId": "OrganizationsWebhooksController_getAllOrganizationWebhooks",
|
||||
@@ -7888,7 +8001,7 @@
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "name",
|
||||
"description": "only allowed value for type is `name`"
|
||||
"description": "only allowed value for type is `name`. Used for having 1 booking field for both first name and last name."
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
@@ -8682,7 +8795,7 @@
|
||||
"boolean"
|
||||
],
|
||||
"example": "name",
|
||||
"description": "only allowed value for type is `name`",
|
||||
"description": "only allowed value for type is `name`. Used for having 1 booking field for both first name and last name.",
|
||||
"default": "name"
|
||||
},
|
||||
"label": {
|
||||
|
||||
+21
-1
@@ -3,7 +3,8 @@ import i18next from "i18next";
|
||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import { headers } from "next/headers";
|
||||
|
||||
import { constructGenericImage } from "@calcom/lib/OgImages";
|
||||
import type { MeetingImageProps } from "@calcom/lib/OgImages";
|
||||
import { constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
||||
import { IS_CALCOM, WEBAPP_URL, APP_NAME, SEO_IMG_OGIMG, CAL_URL } from "@calcom/lib/constants";
|
||||
import { buildCanonical } from "@calcom/lib/next-seo.config";
|
||||
import { truncateOnWord } from "@calcom/lib/text";
|
||||
@@ -103,3 +104,22 @@ export const _generateMetadata = async (
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMeetingMetadata = async (
|
||||
meeting: MeetingImageProps,
|
||||
getTitle: (t: TFunction<string, undefined>) => string,
|
||||
getDescription: (t: TFunction<string, undefined>) => string,
|
||||
hideBranding?: boolean,
|
||||
origin?: string
|
||||
) => {
|
||||
const metadata = await _generateMetadataWithoutImage(getTitle, getDescription, hideBranding, origin);
|
||||
const image = SEO_IMG_OGIMG + constructMeetingImage(meeting);
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
openGraph: {
|
||||
...metadata.openGraph,
|
||||
images: [image],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,12 +10,18 @@ import { userMetadata } from "@calcom/prisma/zod-utils";
|
||||
|
||||
const inputSchema = z.object({
|
||||
customer: z.object({
|
||||
name: z.string().optional(),
|
||||
email: z.string().email(),
|
||||
username: z.string().optional(),
|
||||
timeZone: z.string().optional(),
|
||||
emailVerified: z.boolean().optional(),
|
||||
identityProvider: z.string().optional(),
|
||||
twoFactorEnabled: z.boolean().optional(),
|
||||
lastActiveAt: z.string().optional(),
|
||||
teamName: z.string().optional(),
|
||||
teamSlug: z.string().optional(),
|
||||
isOrganization: z.boolean().optional(),
|
||||
stripeCustomerId: z.string().optional(),
|
||||
}),
|
||||
cardKeys: z.array(z.string()),
|
||||
});
|
||||
@@ -53,168 +59,10 @@ async function handler(request: Request) {
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Email",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: customer.email || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Email Verified?",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentBadge: {
|
||||
badgeLabel: customer.emailVerified ? "Yes" : "No",
|
||||
badgeColor: customer.emailVerified ? "GREEN" : "RED",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Username",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: customer.username || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "User ID",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Time Zone",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: customer.timeZone || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Two Factor Enabled?",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentBadge: {
|
||||
badgeLabel: customer.twoFactorEnabled ? "Yes" : "No",
|
||||
badgeColor: customer.twoFactorEnabled ? "GREEN" : "RED",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Identity Provider",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: customer.identityProvider || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
componentText: {
|
||||
textSize: "L",
|
||||
textColor: "MUTED",
|
||||
text: "User does not exist!",
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -223,18 +71,29 @@ async function handler(request: Request) {
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch team details including userId and team name
|
||||
const teamMemberships = await UserRepository.findTeamsByUserId({ userId: user.id });
|
||||
const firstTeam = teamMemberships.teams[0] ?? null;
|
||||
|
||||
// Parse user metadata
|
||||
const parsedMetadata = userMetadata.parse(user.metadata);
|
||||
|
||||
const cards = await Promise.all(
|
||||
cardExamples.map(async (cardFn) => {
|
||||
return cardFn(
|
||||
user.name || "Unknown",
|
||||
user.email,
|
||||
user.id.toString(),
|
||||
user.username || "Unknown",
|
||||
user.timeZone,
|
||||
user.emailVerified,
|
||||
user.twoFactorEnabled
|
||||
user.twoFactorEnabled,
|
||||
user.identityProvider,
|
||||
user.lastActiveAt,
|
||||
firstTeam?.name || "Unknown",
|
||||
firstTeam?.slug || "Unknown",
|
||||
firstTeam?.isOrganization || false,
|
||||
(user.metadata as { stripeCustomerId?: string })?.stripeCustomerId || "Unknown"
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -4,9 +4,6 @@ import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { EventRepository } from "@calcom/lib/server/repository/event";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/d/[link]/[slug]/getServerSideProps";
|
||||
import { type PageProps } from "@lib/d/[link]/[slug]/getServerSideProps";
|
||||
@@ -17,24 +14,15 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
|
||||
const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
|
||||
const pageProps = await getData(legacyCtx);
|
||||
|
||||
const { booking, user: username, slug: eventSlug, isTeamEvent } = pageProps;
|
||||
const { booking, eventData, isBrandingHidden } = pageProps;
|
||||
const rescheduleUid = booking?.uid;
|
||||
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(legacyCtx.req);
|
||||
const org = isValidOrgDomain ? currentOrgDomain : null;
|
||||
|
||||
const event = await EventRepository.getPublicEvent({
|
||||
username,
|
||||
eventSlug,
|
||||
isTeamEvent,
|
||||
org,
|
||||
fromRedirectOfNonOrgLink: legacyCtx.query.orgRedirection === "true",
|
||||
});
|
||||
|
||||
const profileName = event?.profile?.name ?? "";
|
||||
const title = event?.title ?? "";
|
||||
const profileName = eventData?.profile?.name ?? "";
|
||||
const title = eventData?.title ?? "";
|
||||
return await _generateMetadata(
|
||||
(t) => `${rescheduleUid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
|
||||
(t) => `${rescheduleUid ? t("reschedule") : ""} ${title}`
|
||||
(t) => `${rescheduleUid ? t("reschedule") : ""} ${title}`,
|
||||
isBrandingHidden
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { type PageProps } from "@pages/org/[orgSlug]/[user]/[type]";
|
||||
import Page from "@pages/org/[orgSlug]/[user]/[type]/embed";
|
||||
import withEmbedSsrAppDir from "app/WithEmbedSSR";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import type { OrgTypePageProps } from "app/org/[orgSlug]/[user]/[type]/page";
|
||||
|
||||
import { getServerSideProps } from "@lib/org/[orgSlug]/[user]/[type]/getServerSideProps";
|
||||
|
||||
const getEmbedData = withEmbedSsrAppDir<PageProps>(getServerSideProps);
|
||||
const getEmbedData = withEmbedSsrAppDir<OrgTypePageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({ getLayout: null, getData: getEmbedData, isBookingPage: true, Page });
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import Page, { type PageProps } from "@pages/org/[orgSlug]/[user]/[type]";
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
|
||||
import { getServerSideProps } from "@lib/org/[orgSlug]/[user]/[type]/getServerSideProps";
|
||||
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({ getLayout: null, getData, Page });
|
||||
@@ -1,29 +0,0 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps as _PageProps } from "app/_types";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/team-view";
|
||||
import TeamPage from "~/team/team-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
|
||||
const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
|
||||
|
||||
return await _generateMetadata(
|
||||
(t) => props.team.name || t("nameless_team"),
|
||||
(t) => props.team.name || t("nameless_team")
|
||||
);
|
||||
};
|
||||
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: TeamPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -1,45 +0,0 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps as _PageProps } from "app/_types";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { EventRepository } from "@calcom/lib/server/repository/event";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/type-view";
|
||||
import TypePage from "~/team/type-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
|
||||
const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
|
||||
const props = await getData(legacyCtx);
|
||||
const { user: username, slug: eventSlug, booking } = props;
|
||||
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(legacyCtx.req, legacyCtx.params?.orgSlug);
|
||||
|
||||
const event = await EventRepository.getPublicEvent({
|
||||
username,
|
||||
eventSlug,
|
||||
isTeamEvent: true,
|
||||
org: isValidOrgDomain ? currentOrgDomain : null,
|
||||
fromRedirectOfNonOrgLink: legacyCtx.query.orgRedirection === "true",
|
||||
});
|
||||
|
||||
const profileName = event?.profile?.name ?? "";
|
||||
const title = event?.title ?? "";
|
||||
|
||||
return await _generateMetadata(
|
||||
(t) => `${booking?.uid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
|
||||
(t) => `${booking?.uid ? t("reschedule") : ""} ${title}`
|
||||
);
|
||||
};
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: TypePage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -1,29 +0,0 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps as _PageProps } from "app/_types";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/team-view";
|
||||
import TeamPage from "~/team/team-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
|
||||
const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
|
||||
|
||||
return await _generateMetadata(
|
||||
(t) => props.team.name || t("nameless_team"),
|
||||
(t) => props.team.name || t("nameless_team")
|
||||
);
|
||||
};
|
||||
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: TeamPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -1,11 +0,0 @@
|
||||
import withEmbedSsrAppDir from "app/WithEmbedSSR";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
|
||||
import { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/type-view";
|
||||
import LegacyPage from "~/team/type-view";
|
||||
|
||||
const getEmbedData = withEmbedSsrAppDir<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({ getLayout: null, getData: getEmbedData, Page: LegacyPage })<"P">;
|
||||
@@ -1,44 +0,0 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps } from "app/_types";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { EventRepository } from "@calcom/lib/server/repository/event";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
|
||||
import LegacyPage, { type PageProps as LegacyPageProps } from "~/team/type-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
|
||||
const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
|
||||
const props = await getData(legacyCtx);
|
||||
const { user: username, slug: eventSlug, booking } = props;
|
||||
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(legacyCtx.req, legacyCtx.params?.orgSlug);
|
||||
|
||||
const event = await EventRepository.getPublicEvent({
|
||||
username,
|
||||
eventSlug,
|
||||
isTeamEvent: true,
|
||||
org: isValidOrgDomain ? currentOrgDomain : null,
|
||||
fromRedirectOfNonOrgLink: legacyCtx.query.orgRedirection === "true",
|
||||
});
|
||||
|
||||
const profileName = event?.profile?.name ?? "";
|
||||
const title = event?.title ?? "";
|
||||
|
||||
return await _generateMetadata(
|
||||
(t) => `${booking?.uid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
|
||||
(t) => `${booking?.uid ? t("reschedule") : ""} ${title}`
|
||||
);
|
||||
};
|
||||
const getData = withAppDirSsr<LegacyPageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: LegacyPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -1,11 +0,0 @@
|
||||
import withEmbedSsrAppDir from "app/WithEmbedSSR";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
|
||||
import { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/team-view";
|
||||
import LegacyPage from "~/team/team-view";
|
||||
|
||||
const getEmbedData = withEmbedSsrAppDir<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({ getLayout: null, getData: getEmbedData, Page: LegacyPage })<"P">;
|
||||
@@ -1,28 +0,0 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps as _PageProps } from "app/_types";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/team-view";
|
||||
import LegacyPage from "~/team/team-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
|
||||
const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
|
||||
|
||||
return await _generateMetadata(
|
||||
(t) => props.team.name || t("nameless_team"),
|
||||
(t) => props.team.name || t("nameless_team")
|
||||
);
|
||||
};
|
||||
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: LegacyPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
})<"P">;
|
||||
@@ -0,0 +1,64 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps } from "app/_types";
|
||||
import { generateMeetingMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/org/[orgSlug]/[user]/[type]/getServerSideProps";
|
||||
|
||||
import type { PageProps as TeamTypePageProps } from "~/team/type-view";
|
||||
import TeamTypePage from "~/team/type-view";
|
||||
import UserTypePage from "~/users/views/users-type-public-view";
|
||||
import type { PageProps as UserTypePageProps } from "~/users/views/users-type-public-view";
|
||||
|
||||
export type OrgTypePageProps = UserTypePageProps | TeamTypePageProps;
|
||||
const getData = withAppDirSsr<OrgTypePageProps>(getServerSideProps);
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
|
||||
const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
|
||||
const props = await getData(legacyCtx);
|
||||
|
||||
const { booking, isSEOIndexable, eventData, isBrandingHidden } = props;
|
||||
const rescheduleUid = booking?.uid;
|
||||
|
||||
const profileName = eventData?.profile?.name ?? "";
|
||||
const profileImage = eventData?.profile.image;
|
||||
const title = eventData?.title ?? "";
|
||||
const meeting = {
|
||||
title,
|
||||
profile: { name: profileName, image: profileImage },
|
||||
users: [
|
||||
...(eventData?.users || []).map((user) => ({
|
||||
name: `${user.name}`,
|
||||
username: `${user.username}`,
|
||||
})),
|
||||
],
|
||||
};
|
||||
const metadata = await generateMeetingMetadata(
|
||||
meeting,
|
||||
(t) => `${rescheduleUid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
|
||||
(t) => `${rescheduleUid ? t("reschedule") : ""} ${title}`,
|
||||
isBrandingHidden,
|
||||
getOrgFullOrigin(eventData?.entity.orgSlug ?? null)
|
||||
);
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
robots: {
|
||||
follow: !(eventData?.hidden || !isSEOIndexable),
|
||||
index: !(eventData?.hidden || !isSEOIndexable),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const Page = async (props: OrgTypePageProps) => {
|
||||
if ((props as TeamTypePageProps)?.teamId) {
|
||||
return <TeamTypePage {...(props as TeamTypePageProps)} />;
|
||||
}
|
||||
return <UserTypePage {...(props as UserTypePageProps)} />;
|
||||
};
|
||||
|
||||
export default WithLayout({ getLayout: null, getData, ServerPage: Page, isBookingPage: true });
|
||||
@@ -0,0 +1 @@
|
||||
export { default, generateMetadata } from "app/team/[slug]/page";
|
||||
@@ -0,0 +1 @@
|
||||
export { default, generateMetadata } from "app/team/[slug]/[type]/page";
|
||||
@@ -0,0 +1 @@
|
||||
export { default, generateMetadata } from "app/team/[slug]/page";
|
||||
@@ -0,0 +1,58 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps } from "app/_types";
|
||||
import { generateMeetingMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
|
||||
import LegacyPage from "~/team/type-view";
|
||||
import type { PageProps as LegacyPageProps } from "~/team/type-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
|
||||
const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
|
||||
const props = await getData(legacyCtx);
|
||||
const { booking, isSEOIndexable, eventData, isBrandingHidden } = props;
|
||||
|
||||
const profileName = eventData?.profile?.name ?? "";
|
||||
const profileImage = eventData?.profile.image;
|
||||
const title = eventData?.title ?? "";
|
||||
const meeting = {
|
||||
title,
|
||||
profile: { name: profileName, image: profileImage },
|
||||
users: [
|
||||
...(eventData?.users || []).map((user) => ({
|
||||
name: `${user.name}`,
|
||||
username: `${user.username}`,
|
||||
})),
|
||||
],
|
||||
};
|
||||
|
||||
const metadata = await generateMeetingMetadata(
|
||||
meeting,
|
||||
(t) => `${booking?.uid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
|
||||
(t) => `${booking?.uid ? t("reschedule") : ""} ${title}`,
|
||||
isBrandingHidden,
|
||||
getOrgFullOrigin(eventData.entity.orgSlug ?? null)
|
||||
);
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
robots: {
|
||||
follow: !(eventData?.hidden || !isSEOIndexable),
|
||||
index: !(eventData?.hidden || !isSEOIndexable),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const getData = withAppDirSsr<LegacyPageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: LegacyPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -0,0 +1,52 @@
|
||||
import { withAppDirSsr } from "app/WithAppDirSsr";
|
||||
import type { PageProps as _PageProps } from "app/_types";
|
||||
import { generateMeetingMetadata } from "app/_utils";
|
||||
import { WithLayout } from "app/layoutHOC";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { getOrgOrTeamAvatar } from "@calcom/lib/defaultAvatarImage";
|
||||
|
||||
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
|
||||
import type { PageProps } from "~/team/team-view";
|
||||
import LegacyPage from "~/team/team-view";
|
||||
|
||||
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
|
||||
const { team, markdownStrippedBio, isSEOIndexable, currentOrgDomain } = await getData(
|
||||
buildLegacyCtx(headers(), cookies(), params, searchParams)
|
||||
);
|
||||
|
||||
const meeting = {
|
||||
title: markdownStrippedBio ?? "",
|
||||
profile: {
|
||||
name: `${team.name}`,
|
||||
image: getOrgOrTeamAvatar(team),
|
||||
},
|
||||
};
|
||||
|
||||
const metadata = await generateMeetingMetadata(
|
||||
meeting,
|
||||
(t) => team.name || t("nameless_team"),
|
||||
(t) => team.name || t("nameless_team"),
|
||||
false,
|
||||
getOrgFullOrigin(currentOrgDomain ?? null)
|
||||
);
|
||||
return {
|
||||
...metadata,
|
||||
robots: {
|
||||
follow: isSEOIndexable,
|
||||
index: isSEOIndexable,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const getData = withAppDirSsr<PageProps>(getServerSideProps);
|
||||
|
||||
export default WithLayout({
|
||||
Page: LegacyPage,
|
||||
getData,
|
||||
getLayout: null,
|
||||
isBookingPage: true,
|
||||
})<"P">;
|
||||
@@ -511,9 +511,9 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<tr data-testid="booking-item" className="hover:bg-muted group transition ">
|
||||
<div data-testid="booking-item" className="hover:bg-muted group w-full">
|
||||
<div className="flex flex-col sm:flex-row">
|
||||
<td className="hidden align-top ltr:pl-3 rtl:pr-6 sm:table-cell sm:min-w-[12rem]">
|
||||
<div className="hidden align-top ltr:pl-3 rtl:pr-6 sm:table-cell sm:min-w-[12rem]">
|
||||
<div className="flex h-full items-center">
|
||||
{eventTypeColor && (
|
||||
<div className="h-[70%] w-0.5" style={{ backgroundColor: eventTypeColor }} />
|
||||
@@ -562,8 +562,10 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</td>
|
||||
<td data-testid="title-and-attendees" className={`w-full px-4${isRejected ? " line-through" : ""}`}>
|
||||
</div>
|
||||
<div
|
||||
data-testid="title-and-attendees"
|
||||
className={`w-full px-4${isRejected ? " line-through" : ""}`}>
|
||||
<Link href={bookingLink}>
|
||||
{/* Time and Badges for mobile */}
|
||||
<div className="w-full pb-2 pt-4 sm:hidden">
|
||||
@@ -648,8 +650,8 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</td>
|
||||
<td className="flex w-full flex-col flex-wrap items-end justify-end space-x-2 space-y-2 py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:flex-row sm:flex-nowrap sm:items-start sm:space-y-0 sm:pl-0">
|
||||
</div>
|
||||
<div className="flex w-full flex-col flex-wrap items-end justify-end space-x-2 space-y-2 py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:flex-row sm:flex-nowrap sm:items-start sm:space-y-0 sm:pl-0">
|
||||
{isUpcoming && !isCancelled ? (
|
||||
<>
|
||||
{isPending && <TableActions actions={pendingActions} />}
|
||||
@@ -674,7 +676,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
<TableActions actions={chargeCardActions} />
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</div>
|
||||
</div>
|
||||
<BookingItemBadges
|
||||
booking={booking}
|
||||
@@ -683,7 +685,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
userTimeFormat={userTimeFormat}
|
||||
userTimeZone={userTimeZone}
|
||||
/>
|
||||
</tr>
|
||||
</div>
|
||||
|
||||
{isBookingReroutable(parsedBooking) && (
|
||||
<RerouteDialog
|
||||
@@ -712,7 +714,7 @@ const BookingItemBadges = ({
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
<div className="hidden h-9 flex-row pb-4 pl-6 sm:flex">
|
||||
<div className="hidden h-9 flex-row items-center pb-4 pl-6 sm:flex">
|
||||
{isPending && (
|
||||
<Badge className="ltr:mr-2 rtl:ml-2" variant="orange">
|
||||
{t("unconfirmed")}
|
||||
@@ -1251,11 +1253,9 @@ const AssignmentReasonTooltip = ({ assignmentReason }: { assignmentReason: Assig
|
||||
const badgeTitle = assignmentReasonBadgeTitleMap(assignmentReason.reasonEnum);
|
||||
return (
|
||||
<Tooltip content={<p>{assignmentReason.reasonString}</p>}>
|
||||
<div className="-mt-1">
|
||||
<Badge className="ltr:mr-2 rtl:ml-2" variant="gray">
|
||||
{t(badgeTitle)}
|
||||
</Badge>
|
||||
</div>
|
||||
<Badge className="ltr:mr-2 rtl:ml-2" variant="gray">
|
||||
{t(badgeTitle)}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { Button } from "@calcom/ui";
|
||||
|
||||
type Props = {
|
||||
statusCode?: number | null;
|
||||
@@ -53,21 +56,37 @@ export const ErrorPage: React.FC<Props> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-default min-h-screen px-4">
|
||||
<main className="mx-auto max-w-xl pb-6 pt-16 sm:pt-24">
|
||||
<div className="text-center">
|
||||
<p className="text-emphasis text-sm font-semibold uppercase tracking-wide">{statusCode}</p>
|
||||
<h1 className="text-emphasis mt-2 text-4xl font-extrabold tracking-tight sm:text-5xl">
|
||||
<div className="bg-subtle flex h-screen">
|
||||
<div className="rtl: bg-default m-auto rounded-md p-10 text-right ltr:text-left">
|
||||
<h1 className="font-cal text-emphasis text-6xl">{statusCode}</h1>
|
||||
<h2 className="text-emphasis mt-6 max-w-2xl text-2xl font-medium">
|
||||
It's not you, it's us.
|
||||
</h2>
|
||||
<p className="text-default mb-6 mt-4 max-w-2xl text-sm">
|
||||
Something went wrong on our end. Get in touch with our support team, and we'll get it fixed
|
||||
right away for you.
|
||||
</p>
|
||||
|
||||
<div className="mb-8 flex flex-col">
|
||||
<p className="text-default mb-4 max-w-2xl text-sm">
|
||||
Please provide the following text when contacting support to better help you:
|
||||
</p>
|
||||
<pre className="bg-emphasis text-emphasis w-full max-w-2xl whitespace-normal break-words rounded-md p-4">
|
||||
{message}
|
||||
</h1>
|
||||
</pre>
|
||||
</div>
|
||||
</main>
|
||||
{displayDebug && (
|
||||
<div className="flex-wrap">
|
||||
<ErrorDebugPanel error={error} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button href="mailto:support@cal.com">Contact Support</Button>
|
||||
<Button color="secondary" href="javascript:history.back()" className="ml-2">
|
||||
Go back
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{displayDebug && (
|
||||
<div className="flex-wrap">
|
||||
<ErrorDebugPanel error={error} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -121,6 +121,7 @@ async function getUserPageProps(context: GetServerSidePropsContext) {
|
||||
|
||||
return {
|
||||
props: {
|
||||
eventData,
|
||||
entity: eventData.entity,
|
||||
duration: getMultipleDurationValue(
|
||||
eventData.metadata?.multipleDuration,
|
||||
|
||||
+10
-4
@@ -22,7 +22,6 @@ const safeGet = async <T = any>(key: string): Promise<T | undefined> => {
|
||||
const middleware = async (req: NextRequest): Promise<NextResponse<unknown>> => {
|
||||
const url = req.nextUrl;
|
||||
const requestHeaders = new Headers(req.headers);
|
||||
|
||||
requestHeaders.set("x-url", req.url);
|
||||
|
||||
if (!url.pathname.startsWith("/api")) {
|
||||
@@ -155,6 +154,7 @@ export const config = {
|
||||
matcher: [
|
||||
"/403",
|
||||
"/500",
|
||||
"/icons",
|
||||
"/d/:path*",
|
||||
"/more/:path*",
|
||||
"/maintenance/:path*",
|
||||
@@ -187,14 +187,20 @@ export const config = {
|
||||
"/workflows/:path*",
|
||||
"/getting-started/:path*",
|
||||
"/apps",
|
||||
"/bookings/:status/",
|
||||
"/bookings/:path*",
|
||||
"/video/:path*",
|
||||
"/teams",
|
||||
"/future/teams/",
|
||||
"/teams/:path*",
|
||||
"/signup/:path*",
|
||||
"/settings/:path*",
|
||||
"/reschedule/:path*",
|
||||
"/availability/:path*",
|
||||
"/booking/:path*",
|
||||
"/routing-forms/:path*",
|
||||
"/team/:path*",
|
||||
"/org/[orgSlug]/[user]/[type]",
|
||||
"/org/[orgSlug]/team/[slug]/[type]",
|
||||
"/org/[orgSlug]/team/[slug]",
|
||||
"/org/[orgSlug]",
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { Fragment, ReactElement, useState } from "react";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
useReactTable,
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getSortedRowModel,
|
||||
createColumnHelper,
|
||||
} from "@tanstack/react-table";
|
||||
import type { ReactElement } from "react";
|
||||
import { Fragment, useMemo, useState } from "react";
|
||||
import type { z } from "zod";
|
||||
|
||||
import { WipeMyCalActionButton } from "@calcom/app-store/wipemycalother/components";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
@@ -10,20 +17,20 @@ import { FilterToggle } from "@calcom/features/bookings/components/FilterToggle"
|
||||
import { FiltersContainer } from "@calcom/features/bookings/components/FiltersContainer";
|
||||
import type { filterQuerySchema } from "@calcom/features/bookings/lib/useFilterQuery";
|
||||
import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery";
|
||||
import { DataTableProvider, DataTableWrapper } from "@calcom/features/data-table";
|
||||
import Shell from "@calcom/features/shell/Shell";
|
||||
import { useInViewObserver } from "@calcom/lib/hooks/useInViewObserver";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import type { HorizontalTabItemProps, VerticalTabItemProps } from "@calcom/ui";
|
||||
import { Alert, Button, EmptyScreen, HorizontalTabs } from "@calcom/ui";
|
||||
import { Alert, EmptyScreen, HorizontalTabs } from "@calcom/ui";
|
||||
|
||||
import useMeQuery from "@lib/hooks/useMeQuery";
|
||||
|
||||
import BookingListItem from "@components/booking/BookingListItem";
|
||||
import SkeletonLoader from "@components/booking/SkeletonLoader";
|
||||
|
||||
import { validStatuses } from "~/bookings/lib/validStatuses";
|
||||
import type { validStatuses } from "~/bookings/lib/validStatuses";
|
||||
|
||||
type BookingListingStatus = z.infer<NonNullable<typeof filterQuerySchema>>["status"];
|
||||
type BookingOutput = RouterOutputs["viewer"]["bookings"]["get"]["bookings"][0];
|
||||
@@ -66,7 +73,24 @@ const descriptionByStatus: Record<NonNullable<BookingListingStatus>, string> = {
|
||||
unconfirmed: "unconfirmed_bookings",
|
||||
};
|
||||
|
||||
export default function Bookings({ status }: { status: (typeof validStatuses)[number] }) {
|
||||
type BookingsProps = {
|
||||
status: (typeof validStatuses)[number];
|
||||
};
|
||||
|
||||
export default function Bookings(props: BookingsProps) {
|
||||
return (
|
||||
<DataTableProvider>
|
||||
<BookingsContent {...props} />
|
||||
</DataTableProvider>
|
||||
);
|
||||
}
|
||||
|
||||
type RowData = {
|
||||
booking: BookingOutput;
|
||||
recurringInfo?: RecurringInfo;
|
||||
};
|
||||
|
||||
function BookingsContent({ status }: BookingsProps) {
|
||||
const { data: filterQuery } = useFilterQuery();
|
||||
|
||||
const { t } = useLocale();
|
||||
@@ -87,13 +111,32 @@ export default function Bookings({ status }: { status: (typeof validStatuses)[nu
|
||||
}
|
||||
);
|
||||
|
||||
// Animate page (tab) transitions to look smoothing
|
||||
const columns = useMemo(() => {
|
||||
const columnHelper = createColumnHelper<RowData>();
|
||||
|
||||
const buttonInView = useInViewObserver(() => {
|
||||
if (!query.isFetching && query.hasNextPage && query.status === "success") {
|
||||
query.fetchNextPage();
|
||||
}
|
||||
});
|
||||
return [
|
||||
columnHelper.display({
|
||||
id: "custom-view",
|
||||
cell: (props) => {
|
||||
const { booking, recurringInfo } = props.row.original;
|
||||
return (
|
||||
<BookingListItem
|
||||
key={booking.id}
|
||||
loggedInUser={{
|
||||
userId: user?.id,
|
||||
userTimeZone: user?.timeZone,
|
||||
userTimeFormat: user?.timeFormat,
|
||||
userEmail: user?.email,
|
||||
}}
|
||||
listingStatus={status}
|
||||
recurringInfo={recurringInfo}
|
||||
{...booking}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}),
|
||||
];
|
||||
}, [user, status]);
|
||||
|
||||
const isEmpty = !query.data?.pages[0]?.bookings.length;
|
||||
|
||||
@@ -120,6 +163,27 @@ export default function Bookings({ status }: { status: (typeof validStatuses)[nu
|
||||
return true;
|
||||
};
|
||||
|
||||
const flatData = useMemo(() => {
|
||||
return (
|
||||
query.data?.pages.flatMap((page) =>
|
||||
page.bookings.filter(filterBookings).map((booking) => ({
|
||||
booking,
|
||||
recurringInfo: page.recurringInfo.find(
|
||||
(info) => info.recurringEventId === booking.recurringEventId
|
||||
),
|
||||
}))
|
||||
) || []
|
||||
);
|
||||
}, [query.data]);
|
||||
|
||||
const table = useReactTable<RowData>({
|
||||
data: flatData,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
});
|
||||
|
||||
let recurringInfoToday: RecurringInfo | undefined;
|
||||
|
||||
const bookingsToday =
|
||||
@@ -136,8 +200,6 @@ export default function Bookings({ status }: { status: (typeof validStatuses)[nu
|
||||
})
|
||||
)[0] || [];
|
||||
|
||||
const [animationParentRef] = useAutoAnimate<HTMLDivElement>();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row flex-wrap justify-between">
|
||||
@@ -146,7 +208,7 @@ export default function Bookings({ status }: { status: (typeof validStatuses)[nu
|
||||
</div>
|
||||
<FiltersContainer isFiltersVisible={isFiltersVisible} />
|
||||
<main className="w-full">
|
||||
<div className="flex w-full flex-col" ref={animationParentRef}>
|
||||
<div className="flex w-full flex-col">
|
||||
{query.status === "error" && (
|
||||
<Alert severity="error" title={t("something_went_wrong")} message={query.error.message} />
|
||||
)}
|
||||
@@ -158,69 +220,41 @@ export default function Bookings({ status }: { status: (typeof validStatuses)[nu
|
||||
<WipeMyCalActionButton bookingStatus={status} bookingsEmpty={isEmpty} />
|
||||
<p className="text-subtle mb-2 text-xs font-medium uppercase leading-4">{t("today")}</p>
|
||||
<div className="border-subtle overflow-hidden rounded-md border">
|
||||
<table className="w-full max-w-full table-fixed">
|
||||
<tbody className="bg-default divide-subtle divide-y" data-testid="today-bookings">
|
||||
<Fragment>
|
||||
{bookingsToday.map((booking: BookingOutput) => (
|
||||
<BookingListItem
|
||||
key={booking.id}
|
||||
loggedInUser={{
|
||||
userId: user?.id,
|
||||
userTimeZone: user?.timeZone,
|
||||
userTimeFormat: user?.timeFormat,
|
||||
userEmail: user?.email,
|
||||
}}
|
||||
listingStatus={status}
|
||||
recurringInfo={recurringInfoToday}
|
||||
{...booking}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
</tbody>
|
||||
</table>
|
||||
<div
|
||||
className="bg-default divide-subtle w-full max-w-full divide-y"
|
||||
data-testid="today-bookings">
|
||||
<Fragment>
|
||||
{bookingsToday.map((booking: BookingOutput) => (
|
||||
<BookingListItem
|
||||
key={booking.id}
|
||||
loggedInUser={{
|
||||
userId: user?.id,
|
||||
userTimeZone: user?.timeZone,
|
||||
userTimeFormat: user?.timeFormat,
|
||||
userEmail: user?.email,
|
||||
}}
|
||||
listingStatus={status}
|
||||
recurringInfo={recurringInfoToday}
|
||||
{...booking}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="pt-2 xl:pt-0">
|
||||
<div className="border-subtle overflow-hidden rounded-md border">
|
||||
<table data-testid={`${status}-bookings`} className="w-full max-w-full table-fixed">
|
||||
<tbody className="bg-default divide-subtle divide-y" data-testid="bookings">
|
||||
{query.data.pages.map((page, index) => (
|
||||
<Fragment key={index}>
|
||||
{page.bookings.filter(filterBookings).map((booking: BookingOutput) => {
|
||||
const recurringInfo = page.recurringInfo.find(
|
||||
(info) => info.recurringEventId === booking.recurringEventId
|
||||
);
|
||||
return (
|
||||
<BookingListItem
|
||||
key={booking.id}
|
||||
loggedInUser={{
|
||||
userId: user?.id,
|
||||
userTimeZone: user?.timeZone,
|
||||
userTimeFormat: user?.timeFormat,
|
||||
userEmail: user?.email,
|
||||
}}
|
||||
listingStatus={status}
|
||||
recurringInfo={recurringInfo}
|
||||
{...booking}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="text-default p-4 text-center" ref={buttonInView.ref}>
|
||||
<Button
|
||||
color="minimal"
|
||||
loading={query.isFetchingNextPage}
|
||||
disabled={!query.hasNextPage}
|
||||
onClick={() => query.fetchNextPage()}>
|
||||
{query.hasNextPage ? t("load_more_results") : t("no_more_results")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DataTableWrapper
|
||||
table={table}
|
||||
testId={`${status}-bookings`}
|
||||
bodyTestId="bookings"
|
||||
hideHeader={true}
|
||||
isPending={query.isFetching && !flatData}
|
||||
hasNextPage={query.hasNextPage}
|
||||
fetchNextPage={query.fetchNextPage}
|
||||
isFetching={query.isFetching}
|
||||
variant="compact"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{query.status === "success" && isEmpty && (
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useSearchParams } from "next/navigation";
|
||||
|
||||
import { Booker } from "@calcom/atoms/monorepo";
|
||||
import { getBookerWrapperClasses } from "@calcom/features/bookings/Booker/utils/getBookerWrapperClasses";
|
||||
import { BookerSeo } from "@calcom/features/bookings/components/BookerSeo";
|
||||
|
||||
import type { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
import type { inferSSRProps } from "@lib/types/inferSSRProps";
|
||||
@@ -26,7 +25,6 @@ function Type({
|
||||
slug,
|
||||
user,
|
||||
booking,
|
||||
isEmbed,
|
||||
isBrandingHidden,
|
||||
eventData,
|
||||
isInstantMeeting,
|
||||
@@ -34,33 +32,12 @@ function Type({
|
||||
teamMemberEmail,
|
||||
crmOwnerRecordType,
|
||||
crmAppSlug,
|
||||
isSEOIndexable,
|
||||
isEmbed,
|
||||
}: PageProps) {
|
||||
const searchParams = useSearchParams();
|
||||
const { profile, users, hidden, title } = eventData;
|
||||
|
||||
return (
|
||||
<main className={getBookerWrapperClasses({ isEmbed: !!isEmbed })}>
|
||||
<BookerSeo
|
||||
username={user}
|
||||
eventSlug={slug}
|
||||
rescheduleUid={booking?.uid}
|
||||
hideBranding={isBrandingHidden}
|
||||
isTeamEvent
|
||||
eventData={
|
||||
profile && users && title && hidden !== undefined
|
||||
? {
|
||||
profile,
|
||||
users,
|
||||
title,
|
||||
hidden,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
entity={eventData.entity}
|
||||
bookingData={booking}
|
||||
isSEOIndexable={isSEOIndexable}
|
||||
/>
|
||||
<Booker
|
||||
username={user}
|
||||
eventSlug={slug}
|
||||
@@ -87,6 +64,4 @@ function Type({
|
||||
);
|
||||
}
|
||||
|
||||
Type.isBookingPage = true;
|
||||
|
||||
export default Type;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "4.8.16",
|
||||
"version": "4.9.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
|
||||
@@ -1,18 +1,63 @@
|
||||
/* eslint-disable import/no-anonymous-default-export */
|
||||
import type { Card } from "@pages/api/plain";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
|
||||
export default (
|
||||
name: string,
|
||||
email: string,
|
||||
id: string,
|
||||
username: string,
|
||||
timeZone: string,
|
||||
emailVerified: Date | null,
|
||||
twoFactorEnabled: boolean | null
|
||||
twoFactorEnabled: boolean | null,
|
||||
identityProvider: string | null,
|
||||
lastActiveAt: Date | null,
|
||||
teamName: string | null,
|
||||
teamSlug: string | null,
|
||||
isOrganization: boolean | null,
|
||||
stripeCustomerId: string | null
|
||||
): Card => {
|
||||
return {
|
||||
key: "customer-card",
|
||||
timeToLiveSeconds: null,
|
||||
components: [
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentText: {
|
||||
text: "Basic Information",
|
||||
textColor: "NORMAL",
|
||||
textSize: "L",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Name",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: name || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
@@ -42,31 +87,6 @@ export default (
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Email Verified?",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentBadge: {
|
||||
badgeLabel: emailVerified === null ? "No" : emailVerified ? "Yes" : "No",
|
||||
badgeColor: emailVerified === null ? "RED" : emailVerified ? "GREEN" : "RED",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
@@ -115,6 +135,24 @@ export default (
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentDivider: {
|
||||
dividerSpacingSize: "M",
|
||||
},
|
||||
},
|
||||
// Account Settings Section Title
|
||||
{
|
||||
componentText: {
|
||||
text: "Account Settings",
|
||||
textColor: "NORMAL",
|
||||
textSize: "L",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
@@ -139,6 +177,211 @@ export default (
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Identity Provider",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: identityProvider || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Last Active At",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: lastActiveAt ? dayjs(lastActiveAt).fromNow() : "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentDivider: {
|
||||
dividerSpacingSize: "M",
|
||||
},
|
||||
},
|
||||
// Team Information Section Title
|
||||
{
|
||||
componentText: {
|
||||
text: "Team Information",
|
||||
textColor: "NORMAL",
|
||||
textSize: "L",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Team Name",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: teamName || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Team Slug",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: teamSlug || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Is Organization",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentBadge: {
|
||||
badgeLabel: isOrganization ? "Yes" : "No",
|
||||
badgeColor: isOrganization ? "GREEN" : "RED",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentDivider: {
|
||||
dividerSpacingSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentText: {
|
||||
text: "Security & Billing",
|
||||
textColor: "NORMAL",
|
||||
textSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Stripe Customer ID",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: stripeCustomerId || "Unknown",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
{
|
||||
componentText: {
|
||||
text: "Email Verified?",
|
||||
textColor: "MUTED",
|
||||
},
|
||||
},
|
||||
],
|
||||
rowAsideContent: [
|
||||
{
|
||||
componentBadge: {
|
||||
badgeLabel: emailVerified === null ? "No" : emailVerified ? "Yes" : "No",
|
||||
badgeColor: emailVerified === null ? "RED" : emailVerified ? "GREEN" : "RED",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
componentSpacer: {
|
||||
spacerSize: "M",
|
||||
},
|
||||
},
|
||||
{
|
||||
componentRow: {
|
||||
rowMainContent: [
|
||||
|
||||
@@ -2,10 +2,17 @@ import type { Card } from "@pages/api/plain";
|
||||
import customerCardDisplay from "@pages/api/plain/customer-card-display";
|
||||
|
||||
export const cardExamples: ((
|
||||
name: string,
|
||||
email: string,
|
||||
id: string,
|
||||
username: string,
|
||||
timeZone: string,
|
||||
emailVerified: Date | null,
|
||||
twoFactorEnabled: boolean | null
|
||||
twoFactorEnabled: boolean | null,
|
||||
identityProvider: string | null,
|
||||
lastActiveAt: Date | null,
|
||||
teamName: string | null,
|
||||
teamSlug: string | null,
|
||||
isOrganization: boolean | null,
|
||||
stripeCustomerId: string | null
|
||||
) => Card)[] = [customerCardDisplay];
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
import { getServerSideProps as _getServerSideProps } from "@lib/org/[orgSlug]/[user]/[type]/getServerSideProps";
|
||||
import withEmbedSsr from "@lib/withEmbedSsr";
|
||||
|
||||
import { getServerSideProps as _getServerSideProps } from ".";
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
|
||||
export { default, type PageProps } from ".";
|
||||
import type { PageProps as TeamTypePageProps } from "~/team/type-view";
|
||||
import TeamTypePage from "~/team/type-view";
|
||||
import UserTypePage from "~/users/views/users-type-public-view";
|
||||
import type { PageProps as UserTypePageProps } from "~/users/views/users-type-public-view";
|
||||
|
||||
export type PageProps = UserTypePageProps | TeamTypePageProps;
|
||||
|
||||
export default function Page(props: PageProps) {
|
||||
if ((props as TeamTypePageProps)?.teamId) return <TeamTypePage {...(props as TeamTypePageProps)} />;
|
||||
return <UserTypePage {...(props as UserTypePageProps)} />;
|
||||
}
|
||||
|
||||
Page.PageWrapper = PageWrapper;
|
||||
|
||||
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
|
||||
import type { PageProps as TeamTypePageProps } from "~/team/type-view";
|
||||
import TeamTypePage from "~/team/type-view";
|
||||
import UserTypePage from "~/users/views/users-type-public-view";
|
||||
import type { PageProps as UserTypePageProps } from "~/users/views/users-type-public-view";
|
||||
|
||||
export { getServerSideProps } from "@lib/org/[orgSlug]/[user]/[type]/getServerSideProps";
|
||||
|
||||
export type PageProps = UserTypePageProps | TeamTypePageProps;
|
||||
|
||||
export default function Page(props: PageProps) {
|
||||
if ((props as TeamTypePageProps)?.teamId) return <TeamTypePage {...(props as TeamTypePageProps)} />;
|
||||
return <UserTypePage {...(props as UserTypePageProps)} />;
|
||||
}
|
||||
|
||||
Page.PageWrapper = PageWrapper;
|
||||
@@ -1,7 +1,14 @@
|
||||
import { getServerSideProps as _getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
import withEmbedSsr from "@lib/withEmbedSsr";
|
||||
|
||||
import { getServerSideProps as _getServerSideProps } from "./index";
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
|
||||
export { default } from "./index";
|
||||
import TeamPage, { type PageProps } from "~/team/team-view";
|
||||
|
||||
const Page = (props: PageProps) => <TeamPage {...props} />;
|
||||
|
||||
Page.PageWrapper = PageWrapper;
|
||||
|
||||
export default Page;
|
||||
|
||||
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export { getServerSideProps, default } from "@pages/team/[slug]";
|
||||
@@ -1 +0,0 @@
|
||||
export { getServerSideProps, default } from "@pages/team/[slug]/[type]";
|
||||
@@ -1 +0,0 @@
|
||||
export { getServerSideProps, default } from "@pages/team/[slug]";
|
||||
@@ -1,10 +0,0 @@
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
|
||||
import TeamPage, { type PageProps } from "~/team/team-view";
|
||||
|
||||
const Page = (props: PageProps) => <TeamPage {...props} />;
|
||||
|
||||
Page.PageWrapper = PageWrapper;
|
||||
|
||||
export default Page;
|
||||
export { getServerSideProps } from "@lib/team/[slug]/getServerSideProps";
|
||||
@@ -1,10 +0,0 @@
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
|
||||
import TypePage, { type PageProps } from "~/team/type-view";
|
||||
|
||||
const Page = (props: PageProps) => <TypePage {...props} />;
|
||||
|
||||
Page.PageWrapper = PageWrapper;
|
||||
|
||||
export default Page;
|
||||
export { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
@@ -0,0 +1,15 @@
|
||||
import { expectPageToBeNotFound } from "playwright/lib/testUtils";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.describe("App Router - error handling", () => {
|
||||
test("404s must render App Router's not-found page regardless of whether pages router or app router is used", async ({
|
||||
page,
|
||||
}) => {
|
||||
await expectPageToBeNotFound({ page, url: "/123491234" });
|
||||
await expectPageToBeNotFound({ page, url: "/team/123491234" });
|
||||
await expectPageToBeNotFound({ page, url: "/org/123491234" });
|
||||
await expectPageToBeNotFound({ page, url: "/insights/123491234" });
|
||||
await expectPageToBeNotFound({ page, url: "/login/123491234" });
|
||||
});
|
||||
});
|
||||
@@ -31,6 +31,8 @@ function getOrgOrigin(orgSlug: string | null) {
|
||||
return orgOrigin;
|
||||
}
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Bookings", () => {
|
||||
test.afterEach(async ({ orgs, users, page }) => {
|
||||
await users.deleteAll();
|
||||
|
||||
@@ -68,7 +68,18 @@ async function verifyRobotsMetaTag({ page, orgSlug, urls, expectedContent }: Ver
|
||||
const { url } = await goToUrlWithErrorHandling(relativeUrl);
|
||||
const metaTag = await page.locator('head > meta[name="robots"]');
|
||||
const metaTagValue = await metaTag.getAttribute("content");
|
||||
expect(metaTagValue).toEqual(expectedContent);
|
||||
expect(metaTagValue).not.toBeNull();
|
||||
expect(
|
||||
metaTagValue
|
||||
?.split(",")
|
||||
.map((s) => s.trim())
|
||||
.join(",")
|
||||
).toEqual(
|
||||
expectedContent
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.join(",")
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "يسمح للحاجزين بحجز الاجتماعات عندما يكون المضيف متاحاً. استخدم هذا الخيار لزيادة عدد الاجتماعات المحتملة التي يمكن حجزها عندما يكون التوزيع المتساوي للاجتماعات بين المضيفين أقل أهمية.",
|
||||
"rr_distribution_method_balanced_title": "توازن الأحمال",
|
||||
"rr_distribution_method_balanced_description": "سنراقب عدد الحجوزات التي تمت مع كل مضيف ونقارنها مع الآخرين، مع تعطيل بعض المضيفين الذين تجاوزوا الحد بكثير لضمان توزيع الحجوزات بشكل متساوٍ.",
|
||||
"edit_team_member_weights": "تعديل الأوزان",
|
||||
"weights_updated_successfully": "تم تحديث الأوزان بنجاح",
|
||||
"require_confirmation_for_free_email": "يتطلب التأكيد فقط لمزودي البريد الإلكتروني المجاني (مثل @gmail.com، @outlook.com)",
|
||||
"exclude_emails_that_contain": "استبعاد رسائل البريد الإلكتروني التي تحتوي على ...",
|
||||
"require_emails_that_contain": "يتطلب رسائل بريد إلكتروني تحتوي على ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "أنت تقوم بحجز تجريبي.",
|
||||
"icon_showcase": "معرض الأيقونات",
|
||||
"icons_showcase": "معرض الأيقونات",
|
||||
"feature_currently_disabled": "الميزة معطلة حالياً",
|
||||
"choose_an_option": "اختر خيارًا",
|
||||
"enter_option_value": "أدخل قيمة الخيار",
|
||||
"remove_option": "إزالة الخيار",
|
||||
"managed_users": "المستخدمون المُدارون",
|
||||
"managed_users_description": "عرض جميع المستخدمين المُدارين الذين تم إنشاؤهم بواسطة عميل OAuth الخاص بك",
|
||||
"select_oAuth_client": "اختر عميل OAuth",
|
||||
"on_every_instance": "في كل مثيل",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ أضف السلاسل الجديدة أعلاه هنا ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Görüş təşkilatçısı mövcud olduqda, görüşlərin bron edilməsinə imkan verir. Bu, potensial görüşlərin sayını maksimuma çatdırmaq və görüşlərin təşkilatçılar arasında bərabər paylanmasının daha az əhəmiyyətli olduğu hallarda istifadə olunur.",
|
||||
"rr_distribution_method_balanced_title": "Yük balanslaşdırma",
|
||||
"rr_distribution_method_balanced_description": "Hər bir təşkilatçı ilə neçə bron edildiyini izləyəcəyik və bunu digərləri ilə müqayisə edəcəyik, çox irəlidə olan bəzi təşkilatçıları deaktiv edərək bronların bərabər paylanmasını təmin edəcəyik.",
|
||||
"edit_team_member_weights": "Çəkiləri redaktə et",
|
||||
"weights_updated_successfully": "Çəkilər uğurla yeniləndi",
|
||||
"require_confirmation_for_free_email": "Yalnız pulsuz e-poçt provayderləri üçün təsdiq tələb edin (Məs. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Tərkibində olan e-poçtları istisna et...",
|
||||
"require_emails_that_contain": "E-poçt ünvanları ... tərkibli olmalıdır",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Siz test rezervasiyası edirsiniz.",
|
||||
"icon_showcase": "İkon nümayişi",
|
||||
"icons_showcase": "İkonların nümayişi",
|
||||
"feature_currently_disabled": "Funksiya hazırda deaktivdir",
|
||||
"choose_an_option": "Seçim edin",
|
||||
"enter_option_value": "Seçim dəyərini daxil edin",
|
||||
"remove_option": "Seçimi sil",
|
||||
"managed_users": "İdarə edilən istifadəçilər",
|
||||
"managed_users_description": "OAuth müştəriniz tərəfindən yaradılmış bütün idarə edilən istifadəçiləri görün",
|
||||
"select_oAuth_client": "OAuth müştərisini seçin",
|
||||
"on_every_instance": "Hər nümunədə",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Yeni sətirləri bura əlavə edin ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Позволява на клиентите да запазват срещи, когато има наличен домакин. Използвайте това, за да увеличите максимално броя на потенциалните срещи и когато равномерното разпределение на срещите между домакините е по-малко важно.",
|
||||
"rr_distribution_method_balanced_title": "Балансиране на натоварването",
|
||||
"rr_distribution_method_balanced_description": "Ще следим колко резервации са направени с всеки домакин и ще ги сравняваме с останалите, като деактивираме някои домакини, които са прекалено напред, за да бъдат резервациите равномерно разпределени.",
|
||||
"edit_team_member_weights": "Редактиране на тежести",
|
||||
"weights_updated_successfully": "Тежестите са актуализирани успешно",
|
||||
"require_confirmation_for_free_email": "Изисквайте потвърждение само за безплатни имейл доставчици (напр. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Изключи имейли, които съдържат ...",
|
||||
"require_emails_that_contain": "Изисквай имейли, които съдържат...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Правите тестова резервация.",
|
||||
"icon_showcase": "Галерия с икони",
|
||||
"icons_showcase": "Галерия с икони",
|
||||
"feature_currently_disabled": "Функцията е деактивирана в момента",
|
||||
"choose_an_option": "Изберете опция",
|
||||
"enter_option_value": "Въведете стойност на опцията",
|
||||
"remove_option": "Премахване на опцията",
|
||||
"managed_users": "Управлявани потребители",
|
||||
"managed_users_description": "Вижте всички управлявани потребители, създадени от вашия OAuth клиент",
|
||||
"select_oAuth_client": "Изберете OAuth клиент",
|
||||
"on_every_instance": "При всяко изпълнение",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавете новите си низове над този ред ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permet als usuaris reservar reunions sempre que hi hagi un amfitrió disponible. Utilitzeu-ho per maximitzar el nombre potencial de reunions reservades i quan la distribució equitativa de reunions entre els amfitrions és menys important",
|
||||
"rr_distribution_method_balanced_title": "Equilibri de càrrega",
|
||||
"rr_distribution_method_balanced_description": "Monitoritzarem quantes reserves s'han fet amb cada amfitrió i ho compararem amb els altres, desactivant alguns amfitrions que estiguin massa avançats perquè les reserves es distribueixin uniformement",
|
||||
"edit_team_member_weights": "Editar pesos",
|
||||
"weights_updated_successfully": "Els pesos s'han actualitzat correctament",
|
||||
"require_confirmation_for_free_email": "Requereix confirmació només per a proveïdors de correu gratuït (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excloure correus electrònics que continguin...",
|
||||
"require_emails_that_contain": "Requereix correus electrònics que continguin...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Estàs fent una reserva de prova.",
|
||||
"icon_showcase": "Mostra d'icones",
|
||||
"icons_showcase": "Mostra d'icones",
|
||||
"feature_currently_disabled": "La funcionalitat està actualment desactivada",
|
||||
"choose_an_option": "Tria una opció",
|
||||
"enter_option_value": "Introdueix el valor de l'opció",
|
||||
"remove_option": "Elimina l'opció",
|
||||
"managed_users": "Usuaris gestionats",
|
||||
"managed_users_description": "Veure tots els usuaris gestionats creats pel teu client OAuth",
|
||||
"select_oAuth_client": "Selecciona el client OAuth",
|
||||
"on_every_instance": "A cada instància",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Afegiu les vostres noves cadenes a dalt ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Umožňuje rezervujícím sjednat schůzky kdykoliv, když je hostitel k dispozici. Použijte tuto možnost pro maximalizaci počtu potenciálních schůzek a v případech, kdy rovnoměrné rozdělení schůzek mezi hostitele není tak důležité.",
|
||||
"rr_distribution_method_balanced_title": "Vyvažování zátěže",
|
||||
"rr_distribution_method_balanced_description": "Budeme sledovat, kolik rezervací bylo provedeno u jednotlivých hostitelů a porovnávat je s ostatními. Některé hostitele, kteří jsou příliš napřed, dočasně deaktivujeme, aby byly rezervace rovnoměrně distribuovány.",
|
||||
"edit_team_member_weights": "Upravit váhy",
|
||||
"weights_updated_successfully": "Váhy byly úspěšně aktualizovány",
|
||||
"require_confirmation_for_free_email": "Vyžadovat potvrzení pouze pro poskytovatele bezplatných e-mailů (např. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Vyloučit e-maily obsahující...",
|
||||
"require_emails_that_contain": "Vyžadovat e-maily obsahující ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Provádíte testovací rezervaci.",
|
||||
"icon_showcase": "Ukázka ikon",
|
||||
"icons_showcase": "Ukázka ikon",
|
||||
"feature_currently_disabled": "Funkce je momentálně vypnutá",
|
||||
"choose_an_option": "Vyberte možnost",
|
||||
"enter_option_value": "Zadejte hodnotu možnosti",
|
||||
"remove_option": "Odebrat možnost",
|
||||
"managed_users": "Spravovaní uživatelé",
|
||||
"managed_users_description": "Zobrazit všechny spravované uživatele vytvořené vaším OAuth klientem",
|
||||
"select_oAuth_client": "Vybrat OAuth klienta",
|
||||
"on_every_instance": "Na každé instanci",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Giver bookere mulighed for at booke møder, når en vært er tilgængelig. Brug dette for at maksimere antallet af potentielle møder, der kan bookes, når den jævne fordeling af møder på tværs af værter er mindre vigtig.",
|
||||
"rr_distribution_method_balanced_title": "Load balancing",
|
||||
"rr_distribution_method_balanced_description": "Vi vil overvåge, hvor mange bookinger der er foretaget med hver vært og sammenligne dette med andre, og deaktivere nogle værter, der er for langt foran, så bookinger fordeles jævnt.",
|
||||
"edit_team_member_weights": "Rediger vægtninger",
|
||||
"weights_updated_successfully": "Vægtninger blev opdateret",
|
||||
"require_confirmation_for_free_email": "Kræv kun bekræftelse for gratis email-udbydere (F.eks. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Ekskluder e-mails, der indeholder ...",
|
||||
"require_emails_that_contain": "Kræv e-mails, der indeholder ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Du foretager en testbooking.",
|
||||
"icon_showcase": "Ikonoversigt",
|
||||
"icons_showcase": "Ikonoversigt",
|
||||
"feature_currently_disabled": "Funktionen er i øjeblikket deaktiveret",
|
||||
"choose_an_option": "Vælg en mulighed",
|
||||
"enter_option_value": "Indtast værdi for mulighed",
|
||||
"remove_option": "Fjern mulighed",
|
||||
"managed_users": "Administrerede brugere",
|
||||
"managed_users_description": "Se alle administrerede brugere oprettet af din OAuth-klient",
|
||||
"select_oAuth_client": "Vælg OAuth-klient",
|
||||
"on_every_instance": "På hver forekomst",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Tilføj dine nye strenge ovenfor her ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Ermöglicht Buchenden, Meetings zu buchen, wann immer ein Host verfügbar ist. Nutzen Sie dies, um die Anzahl potenzieller Meetings zu maximieren, wenn die gleichmäßige Verteilung der Meetings auf die Hosts weniger wichtig ist.",
|
||||
"rr_distribution_method_balanced_title": "Lastverteilung",
|
||||
"rr_distribution_method_balanced_description": "Wir überwachen, wie viele Buchungen bei jedem Host eingegangen sind und vergleichen dies mit anderen. Hosts, die zu weit voraus sind, werden temporär deaktiviert, damit die Buchungen gleichmäßig verteilt werden.",
|
||||
"edit_team_member_weights": "Gewichtungen bearbeiten",
|
||||
"weights_updated_successfully": "Gewichtungen erfolgreich aktualisiert",
|
||||
"require_confirmation_for_free_email": "Bestätigung nur für kostenlose E-Mail-Anbieter erforderlich (z.B. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "E-Mails ausschließen, die ... enthalten",
|
||||
"require_emails_that_contain": "E-Mails müssen enthalten ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Sie führen eine Testbuchung durch.",
|
||||
"icon_showcase": "Icon-Übersicht",
|
||||
"icons_showcase": "Icons-Übersicht",
|
||||
"feature_currently_disabled": "Funktion ist derzeit deaktiviert",
|
||||
"choose_an_option": "Option auswählen",
|
||||
"enter_option_value": "Optionswert eingeben",
|
||||
"remove_option": "Option entfernen",
|
||||
"managed_users": "Verwaltete Benutzer",
|
||||
"managed_users_description": "Sehen Sie alle verwalteten Benutzer, die von Ihrem OAuth-Client erstellt wurden",
|
||||
"select_oAuth_client": "OAuth-Client auswählen",
|
||||
"on_every_instance": "Bei jeder Instanz",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Fügen Sie Ihre neuen Code-Zeilen über dieser hinzu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Επιτρέπει στους χρήστες να κάνουν κρατήσεις όποτε είναι διαθέσιμος ένας διοργανωτής. Χρησιμοποιήστε το για να μεγιστοποιήσετε τον αριθμό των πιθανών συναντήσεων και όταν η ομοιόμορφη κατανομή των συναντήσεων μεταξύ των διοργανωτών είναι λιγότερο σημαντική.",
|
||||
"rr_distribution_method_balanced_title": "Εξισορρόπηση φόρτου",
|
||||
"rr_distribution_method_balanced_description": "Θα παρακολουθούμε πόσες κρατήσεις έχουν γίνει με κάθε διοργανωτή και θα τις συγκρίνουμε με άλλους, απενεργοποιώντας κάποιους διοργανωτές που έχουν προχωρήσει πολύ μπροστά ώστε οι κρατήσεις να κατανέμονται ομοιόμορφα.",
|
||||
"edit_team_member_weights": "Επεξεργασία βαρών",
|
||||
"weights_updated_successfully": "Τα βάρη ενημερώθηκαν με επιτυχία",
|
||||
"require_confirmation_for_free_email": "Απαίτηση επιβεβαίωσης μόνο για παρόχους δωρεάν email (π.χ. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Εξαίρεση email που περιέχουν ...",
|
||||
"require_emails_that_contain": "Απαιτούνται emails που περιέχουν ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Κάνετε μια δοκιμαστική κράτηση.",
|
||||
"icon_showcase": "Παρουσίαση εικονιδίων",
|
||||
"icons_showcase": "Παρουσίαση εικονιδίων",
|
||||
"feature_currently_disabled": "Η λειτουργία είναι απενεργοποιημένη",
|
||||
"choose_an_option": "Επιλέξτε μια επιλογή",
|
||||
"enter_option_value": "Εισαγάγετε την τιμή της επιλογής",
|
||||
"remove_option": "Αφαίρεση επιλογής",
|
||||
"managed_users": "Διαχειριζόμενοι χρήστες",
|
||||
"managed_users_description": "Δείτε όλους τους διαχειριζόμενους χρήστες που δημιουργήθηκαν από το OAuth client σας",
|
||||
"select_oAuth_client": "Επιλέξτε OAuth Client",
|
||||
"on_every_instance": "Σε κάθε περίπτωση",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Προσθέστε τις νέες συμβολοσειρές σας πάνω από εδώ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Allows bookers to book meetings whenever a host is available. Use this to maximize the number of potential meetings booked and when the even distribution of meetings across hosts is less important.",
|
||||
"rr_distribution_method_balanced_title": "Load balancing",
|
||||
"rr_distribution_method_balanced_description": "We will monitor how many bookings have been made with each host and compare this with others, disabling some hosts that are too far ahead so bookings are evenly distributed.",
|
||||
"edit_team_member_weights": "Edit Weights",
|
||||
"weights_updated_successfully": "Weights updated successfully",
|
||||
"require_confirmation_for_free_email": "Only require confirmation for free email providers (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Exclude emails that contain ...",
|
||||
"require_emails_that_contain": "Require emails that contain ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "You are doing a test booking.",
|
||||
"icon_showcase": "Icon showcase",
|
||||
"icons_showcase": "Icons showcase",
|
||||
"feature_currently_disabled": "Feature is currently disabled",
|
||||
"choose_an_option": "Choose an option",
|
||||
"enter_option_value": "Enter option value",
|
||||
"remove_option": "Remove option",
|
||||
"managed_users": "Managed Users",
|
||||
"managed_users_description": "See all the managed users created by your OAuth client",
|
||||
"select_oAuth_client": "Select Oauth Client",
|
||||
"on_every_instance": "On every instance",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permite a los usuarios agendar reuniones cuando un anfitrión esté disponible. Usa esta opción para maximizar el número de reuniones potenciales y cuando la distribución equitativa entre anfitriones es menos importante.",
|
||||
"rr_distribution_method_balanced_title": "Equilibrio de carga",
|
||||
"rr_distribution_method_balanced_description": "Monitoreamos cuántas reservas se han realizado con cada anfitrión y las comparamos con otros, deshabilitando algunos anfitriones que están muy adelantados para que las reservas se distribuyan de manera uniforme.",
|
||||
"edit_team_member_weights": "Editar pesos",
|
||||
"weights_updated_successfully": "Pesos actualizados exitosamente",
|
||||
"require_confirmation_for_free_email": "Solo requerir confirmación para proveedores de correo gratuito (Ej. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excluir correos electrónicos que contengan ...",
|
||||
"require_emails_that_contain": "Requerir correos que contengan...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Estás haciendo una reserva de prueba.",
|
||||
"icon_showcase": "Muestra de íconos",
|
||||
"icons_showcase": "Muestra de íconos",
|
||||
"feature_currently_disabled": "La función está desactivada actualmente",
|
||||
"choose_an_option": "Elige una opción",
|
||||
"enter_option_value": "Ingresa el valor de la opción",
|
||||
"remove_option": "Eliminar opción",
|
||||
"managed_users": "Usuarios administrados",
|
||||
"managed_users_description": "Ver todos los usuarios administrados creados por tu cliente OAuth",
|
||||
"select_oAuth_client": "Seleccionar cliente OAuth",
|
||||
"on_every_instance": "En cada instancia",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agrega tus nuevas cadenas arriba de esta línea ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permite a los usuarios reservar reuniones cuando un anfitrión esté disponible. Utiliza esta opción para maximizar el número de reuniones potenciales y cuando la distribución equitativa entre anfitriones sea menos importante.",
|
||||
"rr_distribution_method_balanced_title": "Equilibrio de carga",
|
||||
"rr_distribution_method_balanced_description": "Monitorizaremos cuántas reservas se han realizado con cada anfitrión y las compararemos con otros, deshabilitando algunos anfitriones que estén muy por delante para que las reservas se distribuyan uniformemente.",
|
||||
"edit_team_member_weights": "Editar pesos",
|
||||
"weights_updated_successfully": "Pesos actualizados correctamente",
|
||||
"require_confirmation_for_free_email": "Solo requerir confirmación para proveedores de correo gratuito (Ej. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excluir correos que contengan...",
|
||||
"require_emails_that_contain": "Requerir correos que contengan...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Estás haciendo una reserva de prueba.",
|
||||
"icon_showcase": "Muestra de iconos",
|
||||
"icons_showcase": "Muestra de iconos",
|
||||
"feature_currently_disabled": "La función está actualmente desactivada",
|
||||
"choose_an_option": "Elige una opción",
|
||||
"enter_option_value": "Ingresa el valor de la opción",
|
||||
"remove_option": "Eliminar opción",
|
||||
"managed_users": "Usuarios gestionados",
|
||||
"managed_users_description": "Ver todos los usuarios gestionados creados por tu cliente OAuth",
|
||||
"select_oAuth_client": "Seleccionar cliente OAuth",
|
||||
"on_every_instance": "En cada instancia",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Agregue sus nuevas cadenas arriba ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Võimaldab broneerijatel broneerida kohtumisi alati, kui võõrustaja on saadaval. Kasutage seda, et maksimeerida potentsiaalsete broneeritud kohtumiste arvu, kui kohtumiste ühtlane jaotamine võõrustajate vahel on vähem oluline.",
|
||||
"rr_distribution_method_balanced_title": "Koormuse tasakaalustamine",
|
||||
"rr_distribution_method_balanced_description": "Jälgime, kui palju broneeringuid on tehtud iga võõrustajaga ja võrdleme seda teistega, keelates mõned võõrustajad, kes on liiga kaugel ees, et broneeringud oleksid ühtlaselt jaotatud.",
|
||||
"edit_team_member_weights": "Muuda kaale",
|
||||
"weights_updated_successfully": "Kaalud edukalt uuendatud",
|
||||
"require_confirmation_for_free_email": "Nõua kinnitust ainult tasuta e-posti teenusepakkujate puhul (nt @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Välista e-kirjad, mis sisaldavad ...",
|
||||
"require_emails_that_contain": "Nõutud on e-mailid, mis sisaldavad ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Teed proovibroneeringut.",
|
||||
"icon_showcase": "Ikoonide ülevaade",
|
||||
"icons_showcase": "Ikoonide ülevaade",
|
||||
"feature_currently_disabled": "Funktsioon on praegu välja lülitatud",
|
||||
"choose_an_option": "Vali valik",
|
||||
"enter_option_value": "Sisesta valiku väärtus",
|
||||
"remove_option": "Eemalda valik",
|
||||
"managed_users": "Hallatavad kasutajad",
|
||||
"managed_users_description": "Vaata kõiki hallatavaid kasutajaid, mis on loodud sinu OAuth kliendi poolt",
|
||||
"select_oAuth_client": "Vali OAuth klient",
|
||||
"on_every_instance": "Igal korral",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Erreserbatzaileei bilerak erreserbatzeko aukera ematen die ostalari bat erabilgarri dagoenean. Erabili hau bilera potentzialen kopurua maximizatzeko eta ostalarien arteko banaketa orekatua hain garrantzitsua ez denean",
|
||||
"rr_distribution_method_balanced_title": "Karga orekatzea",
|
||||
"rr_distribution_method_balanced_description": "Ostalari bakoitzarekin egin diren erreserben kopurua monitorizatu eta besteekin konparatuko dugu, aurreregi doazen ostalari batzuk desgaituz erreserbak modu orekatuan banatzeko",
|
||||
"edit_team_member_weights": "Pisuak editatu",
|
||||
"weights_updated_successfully": "Pisuak behar bezala eguneratu dira",
|
||||
"require_confirmation_for_free_email": "Baieztapena eskatu soilik doako posta elektronikoko hornitzaileentzat (Adib. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Baztertu hau duten emailak...",
|
||||
"require_emails_that_contain": "Helbide elektronikoak hau eduki behar du ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Proba-erreserba bat egiten ari zara.",
|
||||
"icon_showcase": "Ikonoen erakusleihoa",
|
||||
"icons_showcase": "Ikonoen erakusleihoa",
|
||||
"feature_currently_disabled": "Eginbidea desgaituta dago",
|
||||
"choose_an_option": "Aukeratu aukera bat",
|
||||
"enter_option_value": "Sartu aukeraren balioa",
|
||||
"remove_option": "Kendu aukera",
|
||||
"managed_users": "Kudeatutako erabiltzaileak",
|
||||
"managed_users_description": "Ikusi zure OAuth bezeroak sortutako kudeatutako erabiltzaile guztiak",
|
||||
"select_oAuth_client": "Hautatu OAuth bezeroa",
|
||||
"on_every_instance": "Instantzia bakoitzean",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Gehitu zure kate berriak honen gainean ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Sallii varaajien tehdä varauksia aina kun isäntä on saatavilla. Käytä tätä maksimoidaksesi mahdollisten varausten määrän ja kun tapaamisten tasainen jakautuminen isäntien kesken ei ole niin tärkeää.",
|
||||
"rr_distribution_method_balanced_title": "Kuormituksen tasaus",
|
||||
"rr_distribution_method_balanced_description": "Seuraamme kunkin isännän varausmääriä ja vertaamme niitä muihin. Poistamme käytöstä isäntiä, joilla on liikaa varauksia, jotta varaukset jakautuvat tasaisesti.",
|
||||
"edit_team_member_weights": "Muokkaa painotuksia",
|
||||
"weights_updated_successfully": "Painotukset päivitetty onnistuneesti",
|
||||
"require_confirmation_for_free_email": "Vaadi vahvistus vain ilmaisten sähköpostipalvelujen käyttäjiltä (esim. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Sulje pois sähköpostit, jotka sisältävät ...",
|
||||
"require_emails_that_contain": "Vaadi sähköpostit, jotka sisältävät ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Teet testikäyntivarausta.",
|
||||
"icon_showcase": "Kuvakegalleria",
|
||||
"icons_showcase": "Kuvakegalleria",
|
||||
"feature_currently_disabled": "Ominaisuus on tällä hetkellä pois käytöstä",
|
||||
"choose_an_option": "Valitse vaihtoehto",
|
||||
"enter_option_value": "Syötä vaihtoehdon arvo",
|
||||
"remove_option": "Poista vaihtoehto",
|
||||
"managed_users": "Hallinnoidut käyttäjät",
|
||||
"managed_users_description": "Näe kaikki OAuth-asiakassovelluksesi luomat hallinnoidut käyttäjät",
|
||||
"select_oAuth_client": "Valitse OAuth-asiakassovellus",
|
||||
"on_every_instance": "Jokaisessa instanssissa",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Lisää uudet merkkijonot tämän yläpuolelle ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permet aux participants de réserver des réunions dès qu'un hôte est disponible. Utilisez cette option pour maximiser le nombre potentiel de réunions réservées lorsque la distribution équitable des réunions entre les hôtes est moins importante.",
|
||||
"rr_distribution_method_balanced_title": "Équilibrage de charge",
|
||||
"rr_distribution_method_balanced_description": "Nous surveillerons le nombre de réservations effectuées avec chaque hôte et le comparerons avec les autres, en désactivant certains hôtes trop en avance pour que les réservations soient réparties équitablement.",
|
||||
"edit_team_member_weights": "Modifier les pondérations",
|
||||
"weights_updated_successfully": "Pondérations mises à jour avec succès",
|
||||
"require_confirmation_for_free_email": "Exiger une confirmation uniquement pour les fournisseurs de messagerie gratuits (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Exclure les e-mails contenant ...",
|
||||
"require_emails_that_contain": "Exiger des e-mails qui contiennent...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Vous effectuez une réservation test.",
|
||||
"icon_showcase": "Présentation des icônes",
|
||||
"icons_showcase": "Présentation des icônes",
|
||||
"feature_currently_disabled": "La fonctionnalité est actuellement désactivée",
|
||||
"choose_an_option": "Choisir une option",
|
||||
"enter_option_value": "Saisir la valeur de l'option",
|
||||
"remove_option": "Supprimer l'option",
|
||||
"managed_users": "Utilisateurs gérés",
|
||||
"managed_users_description": "Voir tous les utilisateurs gérés créés par votre client OAuth",
|
||||
"select_oAuth_client": "Sélectionner le client OAuth",
|
||||
"on_every_instance": "Sur chaque instance",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "מאפשר לקובעי פגישות לקבוע פגישות בכל פעם שמארח זמין. השתמשו באפשרות זו כדי למקסם את מספר הפגישות הפוטנציאליות ובמקרים בהם חלוקה שווה של פגישות בין המארחים פחות חשובה",
|
||||
"rr_distribution_method_balanced_title": "איזון עומסים",
|
||||
"rr_distribution_method_balanced_description": "אנחנו נעקוב אחר מספר ההזמנות שנקבעו עם כל מארח ונשווה זאת לאחרים, תוך השבתה זמנית של מארחים שקיבלו יותר מדי הזמנות כדי להבטיח חלוקה שווה",
|
||||
"edit_team_member_weights": "עריכת משקולות",
|
||||
"weights_updated_successfully": "המשקולות עודכנו בהצלחה",
|
||||
"require_confirmation_for_free_email": "דרוש אישור רק עבור ספקי אימייל חינמיים (לדוגמה @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "הוצא כתובות דוא\"ל המכילות...",
|
||||
"require_emails_that_contain": "נדרשות כתובות דוא\"ל המכילות...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "אתה מבצע הזמנת ניסיון.",
|
||||
"icon_showcase": "תצוגת אייקון",
|
||||
"icons_showcase": "תצוגת אייקונים",
|
||||
"feature_currently_disabled": "התכונה מושבתת כרגע",
|
||||
"choose_an_option": "בחר אפשרות",
|
||||
"enter_option_value": "הזן ערך אפשרות",
|
||||
"remove_option": "הסר אפשרות",
|
||||
"managed_users": "משתמשים מנוהלים",
|
||||
"managed_users_description": "צפה בכל המשתמשים המנוהלים שנוצרו על ידי לקוח OAuth שלך",
|
||||
"select_oAuth_client": "בחר לקוח OAuth",
|
||||
"on_every_instance": "בכל מופע",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Lehetővé teszi a foglalóknak, hogy találkozókat foglaljanak, amikor a házigazda elérhető. Használja ezt a lehetőséget a potenciális találkozók számának maximalizálására, amikor a találkozók egyenletes elosztása a házigazdák között kevésbé fontos.",
|
||||
"rr_distribution_method_balanced_title": "Terheléselosztás",
|
||||
"rr_distribution_method_balanced_description": "Figyelemmel kísérjük, hogy hány foglalás történt az egyes házigazdákkal, és összehasonlítjuk másokkal, letiltva azokat a házigazdákat, akik túl sok foglalással rendelkeznek, így a foglalások egyenletesen oszlanak el.",
|
||||
"edit_team_member_weights": "Súlyok szerkesztése",
|
||||
"weights_updated_successfully": "A súlyok sikeresen frissítve",
|
||||
"require_confirmation_for_free_email": "Csak ingyenes e-mail szolgáltatók esetén kérjen megerősítést (Pl. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Zárja ki azokat az e-maileket, amelyek tartalmazzák ...",
|
||||
"require_emails_that_contain": "E-mail címek szükségesek, amelyek tartalmazzák ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Tesztfoglalást végzel.",
|
||||
"icon_showcase": "Ikon bemutató",
|
||||
"icons_showcase": "Ikonok bemutatója",
|
||||
"feature_currently_disabled": "A funkció jelenleg ki van kapcsolva",
|
||||
"choose_an_option": "Válassz egy opciót",
|
||||
"enter_option_value": "Add meg az opció értékét",
|
||||
"remove_option": "Opció eltávolítása",
|
||||
"managed_users": "Kezelt felhasználók",
|
||||
"managed_users_description": "Az OAuth kliense által létrehozott összes kezelt felhasználó megtekintése",
|
||||
"select_oAuth_client": "OAuth kliens kiválasztása",
|
||||
"on_every_instance": "Minden példányon",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Adja hozzá az új karakterláncokat fent ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permette ai prenotanti di fissare incontri ogni volta che un host è disponibile. Usa questa opzione per massimizzare il numero di potenziali incontri prenotabili e quando la distribuzione uniforme degli incontri tra gli host è meno importante.",
|
||||
"rr_distribution_method_balanced_title": "Bilanciamento del carico",
|
||||
"rr_distribution_method_balanced_description": "Monitoreremo quante prenotazioni sono state effettuate con ciascun host e le confronteremo con gli altri, disabilitando alcuni host che sono troppo avanti per garantire una distribuzione uniforme delle prenotazioni.",
|
||||
"edit_team_member_weights": "Modifica pesi",
|
||||
"weights_updated_successfully": "Pesi aggiornati con successo",
|
||||
"require_confirmation_for_free_email": "Richiedi conferma solo per i provider di posta elettronica gratuiti (Es. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Escludi le email che contengono ...",
|
||||
"require_emails_that_contain": "Richiedi email che contengono ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Stai effettuando una prenotazione di prova.",
|
||||
"icon_showcase": "Galleria delle icone",
|
||||
"icons_showcase": "Galleria delle icone",
|
||||
"feature_currently_disabled": "La funzionalità è attualmente disattivata",
|
||||
"choose_an_option": "Scegli un'opzione",
|
||||
"enter_option_value": "Inserisci il valore dell'opzione",
|
||||
"remove_option": "Rimuovi opzione",
|
||||
"managed_users": "Utenti gestiti",
|
||||
"managed_users_description": "Visualizza tutti gli utenti gestiti creati dal tuo client OAuth",
|
||||
"select_oAuth_client": "Seleziona client OAuth",
|
||||
"on_every_instance": "Su ogni istanza",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Aggiungi le tue nuove stringhe qui sopra ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "ホストが対応可能な時はいつでも予約を受け付けることができます。潜在的な予約数を最大化したい場合や、ホスト間での予約の均等な配分が重要でない場合に使用します。",
|
||||
"rr_distribution_method_balanced_title": "負荷分散",
|
||||
"rr_distribution_method_balanced_description": "各ホストの予約数を監視し、他のホストと比較して予約数が多すぎるホストを一時的に無効にすることで、予約を均等に配分します。",
|
||||
"edit_team_member_weights": "ウェイトを編集",
|
||||
"weights_updated_successfully": "ウェイトが正常に更新されました",
|
||||
"require_confirmation_for_free_email": "フリーメールプロバイダー(@gmail.com、@outlook.comなど)のみ確認を必要とする",
|
||||
"exclude_emails_that_contain": "...を含むメールアドレスを除外",
|
||||
"require_emails_that_contain": "メールアドレスに含まれる必要がある文字列...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "テスト予約を実行中です。",
|
||||
"icon_showcase": "アイコンショーケース",
|
||||
"icons_showcase": "アイコンショーケース",
|
||||
"feature_currently_disabled": "この機能は現在無効になっています",
|
||||
"choose_an_option": "オプションを選択",
|
||||
"enter_option_value": "オプション値を入力",
|
||||
"remove_option": "オプションを削除",
|
||||
"managed_users": "管理対象ユーザー",
|
||||
"managed_users_description": "OAuthクライアントによって作成された管理対象ユーザーをすべて表示",
|
||||
"select_oAuth_client": "OAuthクライアントを選択",
|
||||
"on_every_instance": "すべてのインスタンスで",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ この上に新しい文字列を追加してください ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "អនុញ្ញាតឱ្យអ្នកកក់អាចកក់កិច្ចប្រជុំនៅពេលដែលម្ចាស់មានពេលទំនេរ។ ប្រើវាដើម្បីបង្កើនចំនួនកិច្ចប្រជុំដែលអាចកក់បាន និងនៅពេលដែលការចែកចាយស្មើគ្នានៃកិច្ចប្រជុំរវាងម្ចាស់មានសារៈសំខាន់តិចជាង។",
|
||||
"rr_distribution_method_balanced_title": "ការរក្សាតុល្យភាពបន្ទុក",
|
||||
"rr_distribution_method_balanced_description": "យើងនឹងតាមដានចំនួនការកក់ដែលបានធ្វើឡើងជាមួយម្ចាស់នីមួយៗ និងប្រៀបធៀបជាមួយអ្នកផ្សេងទៀត ដោយបិទម្ចាស់មួយចំនួនដែលមានការកក់ច្រើនពេកដើម្បីឱ្យការកក់ត្រូវបានចែកចាយស្មើៗគ្នា។",
|
||||
"edit_team_member_weights": "កែសម្រួលទម្ងន់",
|
||||
"weights_updated_successfully": "ការធ្វើបច្ចុប្បន្នភាពទម្ងន់បានជោគជ័យ",
|
||||
"require_confirmation_for_free_email": "តម្រូវឱ្យមានការបញ្ជាក់សម្រាប់តែអ្នកផ្តល់សេវាអ៊ីមែលឥតគិតថ្លៃប៉ុណ្ណោះ (ឧទាហរណ៍៖ @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "ច្រានចោលអ៊ីមែលដែលមាន ...",
|
||||
"require_emails_that_contain": "តម្រូវអ៊ីមែលដែលមាន...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "អ្នកកំពុងធ្វើការកក់សាកល្បង។",
|
||||
"icon_showcase": "ការបង្ហាញរូបតំណាង",
|
||||
"icons_showcase": "ការបង្ហាញរូបតំណាងនានា",
|
||||
"feature_currently_disabled": "មុខងារត្រូវបានបិទដំណើរការនាពេលបច្ចុប្បន្ន",
|
||||
"choose_an_option": "ជ្រើសរើសជម្រើសមួយ",
|
||||
"enter_option_value": "បញ្ចូលតម្លៃជម្រើស",
|
||||
"remove_option": "លុបជម្រើស",
|
||||
"managed_users": "អ្នកប្រើប្រាស់ដែលគ្រប់គ្រង",
|
||||
"managed_users_description": "មើលអ្នកប្រើប្រាស់ដែលគ្រប់គ្រងទាំងអស់ដែលបានបង្កើតដោយ OAuth client របស់អ្នក",
|
||||
"select_oAuth_client": "ជ្រើសរើស OAuth Client",
|
||||
"on_every_instance": "នៅលើគ្រប់ករណី",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ បន្ថែមខ្សែអក្សរថ្មីរបស់អ្នកនៅខាងលើនេះ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "호스트가 가능한 시간대에 예약자가 미팅을 예약할 수 있습니다. 호스트 간 미팅 분배의 균형보다 잠재적 미팅 예약 수를 최대화하고 싶을 때 사용하세요.",
|
||||
"rr_distribution_method_balanced_title": "부하 분산",
|
||||
"rr_distribution_method_balanced_description": "각 호스트의 예약 수를 모니터링하고 다른 호스트들과 비교하여, 예약이 균등하게 분배되도록 예약이 너무 많은 호스트를 일시적으로 비활성화합니다.",
|
||||
"edit_team_member_weights": "가중치 수정",
|
||||
"weights_updated_successfully": "가중치가 성공적으로 업데이트되었습니다",
|
||||
"require_confirmation_for_free_email": "무료 이메일 제공업체(@gmail.com, @outlook.com 등)에 대해서만 확인 필요",
|
||||
"exclude_emails_that_contain": "다음이 포함된 이메일 제외 ...",
|
||||
"require_emails_that_contain": "허용된 이메일 도메인 ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "테스트 예약을 진행하고 있습니다.",
|
||||
"icon_showcase": "아이콘 쇼케이스",
|
||||
"icons_showcase": "아이콘 쇼케이스",
|
||||
"feature_currently_disabled": "현재 기능이 비활성화되어 있습니다",
|
||||
"choose_an_option": "옵션 선택",
|
||||
"enter_option_value": "옵션 값 입력",
|
||||
"remove_option": "옵션 삭제",
|
||||
"managed_users": "관리 대상 사용자",
|
||||
"managed_users_description": "OAuth 클라이언트가 생성한 모든 관리 대상 사용자 보기",
|
||||
"select_oAuth_client": "OAuth 클라이언트 선택",
|
||||
"on_every_instance": "모든 인스턴스에서",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 여기에 새 문자열을 추가하세요 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Stelt boekers in staat om afspraken te maken wanneer een host beschikbaar is. Gebruik dit om het aantal potentiële afspraken te maximaliseren en wanneer de gelijke verdeling van afspraken over hosts minder belangrijk is.",
|
||||
"rr_distribution_method_balanced_title": "Evenredige verdeling",
|
||||
"rr_distribution_method_balanced_description": "We monitoren hoeveel boekingen er bij elke host zijn gemaakt en vergelijken dit met anderen. Hosts die te ver voorlopen worden tijdelijk uitgeschakeld zodat boekingen gelijkmatig worden verdeeld.",
|
||||
"edit_team_member_weights": "Gewichten bewerken",
|
||||
"weights_updated_successfully": "Gewichten succesvol bijgewerkt",
|
||||
"require_confirmation_for_free_email": "Vereist alleen bevestiging voor gratis e-mailproviders (bijv. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "E-mailadressen uitsluiten die ... bevatten",
|
||||
"require_emails_that_contain": "E-mailadressen moeten bevatten ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Je doet een testboeking.",
|
||||
"icon_showcase": "Icoon overzicht",
|
||||
"icons_showcase": "Iconen overzicht",
|
||||
"feature_currently_disabled": "Functie is momenteel uitgeschakeld",
|
||||
"choose_an_option": "Kies een optie",
|
||||
"enter_option_value": "Voer optiewaarde in",
|
||||
"remove_option": "Optie verwijderen",
|
||||
"managed_users": "Beheerde gebruikers",
|
||||
"managed_users_description": "Bekijk alle beheerde gebruikers die zijn aangemaakt door je OAuth-client",
|
||||
"select_oAuth_client": "Selecteer OAuth-client",
|
||||
"on_every_instance": "Op elke instantie",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Voeg uw nieuwe strings hierboven toe ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Lar personer bestille møter når som helst en vert er tilgjengelig. Bruk dette for å maksimere antall potensielle møter som kan bestilles, og når jevn fordeling av møter mellom verter er mindre viktig.",
|
||||
"rr_distribution_method_balanced_title": "Lastbalansering",
|
||||
"rr_distribution_method_balanced_description": "Vi vil overvåke hvor mange bestillinger som er gjort med hver vert og sammenligne dette med andre, og deaktivere enkelte verter som ligger for langt foran slik at bestillinger blir jevnt fordelt.",
|
||||
"edit_team_member_weights": "Rediger vekting",
|
||||
"weights_updated_successfully": "Vekting ble oppdatert",
|
||||
"require_confirmation_for_free_email": "Krev kun bekreftelse for gratis e-postleverandører (f.eks. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Ekskluder e-poster som inneholder ...",
|
||||
"require_emails_that_contain": "Krev e-postadresser som inneholder ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Du gjør en testbestilling.",
|
||||
"icon_showcase": "Ikonvisning",
|
||||
"icons_showcase": "Ikonvisning",
|
||||
"feature_currently_disabled": "Funksjonen er deaktivert",
|
||||
"choose_an_option": "Velg et alternativ",
|
||||
"enter_option_value": "Skriv inn alternativverdi",
|
||||
"remove_option": "Fjern alternativ",
|
||||
"managed_users": "Administrerte brukere",
|
||||
"managed_users_description": "Se alle administrerte brukere opprettet av OAuth-klienten din",
|
||||
"select_oAuth_client": "Velg OAuth-klient",
|
||||
"on_every_instance": "På hver instans",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Legg til dine nye strenger over her ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Umożliwia rezerwację spotkań, gdy którykolwiek z gospodarzy jest dostępny. Używaj tej opcji, aby zmaksymalizować liczbę potencjalnych spotkań, gdy równomierne rozłożenie spotkań między gospodarzami jest mniej istotne.",
|
||||
"rr_distribution_method_balanced_title": "Równoważenie obciążenia",
|
||||
"rr_distribution_method_balanced_description": "System będzie monitorować liczbę rezerwacji przypisanych do każdego gospodarza i porównywać ją z innymi, dezaktywując tymczasowo gospodarzy z większą liczbą spotkań, aby zapewnić równomierną dystrybucję.",
|
||||
"edit_team_member_weights": "Edytuj wagi",
|
||||
"weights_updated_successfully": "Wagi zostały zaktualizowane pomyślnie",
|
||||
"require_confirmation_for_free_email": "Wymagaj potwierdzenia tylko dla dostawców darmowej poczty (np. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Wyklucz e-maile, które zawierają ...",
|
||||
"require_emails_that_contain": "Wymagaj adresów e-mail zawierających...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Wykonujesz testową rezerwację.",
|
||||
"icon_showcase": "Prezentacja ikon",
|
||||
"icons_showcase": "Prezentacja ikon",
|
||||
"feature_currently_disabled": "Funkcja jest obecnie wyłączona",
|
||||
"choose_an_option": "Wybierz opcję",
|
||||
"enter_option_value": "Wprowadź wartość opcji",
|
||||
"remove_option": "Usuń opcję",
|
||||
"managed_users": "Zarządzani użytkownicy",
|
||||
"managed_users_description": "Zobacz wszystkich zarządzanych użytkowników utworzonych przez twojego klienta OAuth",
|
||||
"select_oAuth_client": "Wybierz klienta OAuth",
|
||||
"on_every_instance": "W każdej instancji",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Dodaj nowe ciągi powyżej ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permite que os agendadores marquem reuniões sempre que um anfitrião estiver disponível. Use isso para maximizar o número de reuniões potenciais agendadas quando a distribuição uniforme de reuniões entre os anfitriões for menos importante.",
|
||||
"rr_distribution_method_balanced_title": "Balanceamento de carga",
|
||||
"rr_distribution_method_balanced_description": "Monitoraremos quantas reservas foram feitas com cada anfitrião e compararemos com os outros, desativando alguns anfitriões que estão muito à frente para que as reservas sejam distribuídas uniformemente.",
|
||||
"edit_team_member_weights": "Editar pesos",
|
||||
"weights_updated_successfully": "Pesos atualizados com sucesso",
|
||||
"require_confirmation_for_free_email": "Exigir confirmação apenas para provedores de e-mail gratuitos (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excluir e-mails que contêm ...",
|
||||
"require_emails_that_contain": "Exigir emails que contenham ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Você está fazendo um agendamento de teste.",
|
||||
"icon_showcase": "Mostruário de ícones",
|
||||
"icons_showcase": "Mostruário de ícones",
|
||||
"feature_currently_disabled": "O recurso está desativado no momento",
|
||||
"choose_an_option": "Escolha uma opção",
|
||||
"enter_option_value": "Digite o valor da opção",
|
||||
"remove_option": "Remover opção",
|
||||
"managed_users": "Usuários gerenciados",
|
||||
"managed_users_description": "Veja todos os usuários gerenciados criados pelo seu cliente OAuth",
|
||||
"select_oAuth_client": "Selecionar cliente OAuth",
|
||||
"on_every_instance": "Em cada instância",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Adicione suas novas strings aqui em cima ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permite que os agendadores marquem reuniões sempre que um anfitrião estiver disponível. Use isso para maximizar o número de reuniões potenciais agendadas quando a distribuição uniforme de reuniões entre os anfitriões for menos importante.",
|
||||
"rr_distribution_method_balanced_title": "Balanceamento de carga",
|
||||
"rr_distribution_method_balanced_description": "Monitoraremos quantas reservas foram feitas com cada anfitrião e compararemos com os outros, desativando alguns anfitriões que estão muito à frente para que as reservas sejam distribuídas uniformemente.",
|
||||
"edit_team_member_weights": "Editar pesos",
|
||||
"weights_updated_successfully": "Pesos atualizados com sucesso",
|
||||
"require_confirmation_for_free_email": "Exigir confirmação apenas para provedores de e-mail gratuitos (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excluir emails que contêm ...",
|
||||
"require_emails_that_contain": "Exigir emails que contenham ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Você está fazendo uma reserva de teste.",
|
||||
"icon_showcase": "Mostruário de ícones",
|
||||
"icons_showcase": "Mostruário de ícones",
|
||||
"feature_currently_disabled": "Recurso está atualmente desativado",
|
||||
"choose_an_option": "Escolha uma opção",
|
||||
"enter_option_value": "Digite o valor da opção",
|
||||
"remove_option": "Remover opção",
|
||||
"managed_users": "Usuários gerenciados",
|
||||
"managed_users_description": "Veja todos os usuários gerenciados criados pelo seu cliente OAuth",
|
||||
"select_oAuth_client": "Selecionar cliente OAuth",
|
||||
"on_every_instance": "Em cada instância",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Permite programatorilor să rezerve întâlniri oricând un host este disponibil. Folosește această opțiune pentru a maximiza numărul potențial de întâlniri programate și când distribuția uniformă a întâlnirilor între hosți este mai puțin importantă.",
|
||||
"rr_distribution_method_balanced_title": "Echilibrarea încărcării",
|
||||
"rr_distribution_method_balanced_description": "Vom monitoriza câte rezervări au fost făcute cu fiecare host și vom compara acest lucru cu ceilalți, dezactivând temporar hosții care au prea multe programări, astfel încât rezervările să fie distribuite uniform.",
|
||||
"edit_team_member_weights": "Editare ponderi",
|
||||
"weights_updated_successfully": "Ponderile au fost actualizate cu succes",
|
||||
"require_confirmation_for_free_email": "Solicită confirmare doar pentru furnizorii de email gratuit (Ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Excludează emailurile care conțin ...",
|
||||
"require_emails_that_contain": "Necesită adrese de email care conțin ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Efectuați o rezervare de test.",
|
||||
"icon_showcase": "Prezentare pictograme",
|
||||
"icons_showcase": "Prezentare pictograme",
|
||||
"feature_currently_disabled": "Funcționalitatea este momentan dezactivată",
|
||||
"choose_an_option": "Alege o opțiune",
|
||||
"enter_option_value": "Introdu valoarea opțiunii",
|
||||
"remove_option": "Elimină opțiunea",
|
||||
"managed_users": "Utilizatori administrați",
|
||||
"managed_users_description": "Vezi toți utilizatorii administrați creați de clientul tău OAuth",
|
||||
"select_oAuth_client": "Selectează clientul OAuth",
|
||||
"on_every_instance": "La fiecare instanță",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Adăugați stringurile noi deasupra acestui rând ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Позволяет участникам бронировать встречи, когда организатор доступен. Используйте этот метод для максимизации количества потенциальных встреч, когда равномерное распределение встреч между организаторами менее важно.",
|
||||
"rr_distribution_method_balanced_title": "Балансировка нагрузки",
|
||||
"rr_distribution_method_balanced_description": "Мы будем отслеживать количество бронирований у каждого организатора и сравнивать их между собой, отключая тех организаторов, у которых слишком много встреч, чтобы обеспечить равномерное распределение.",
|
||||
"edit_team_member_weights": "Изменить веса",
|
||||
"weights_updated_successfully": "Веса успешно обновлены",
|
||||
"require_confirmation_for_free_email": "Требовать подтверждение только для бесплатных почтовых сервисов (например, @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Исключить email-адреса, содержащие...",
|
||||
"require_emails_that_contain": "Требуются email-адреса, содержащие...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Вы выполняете тестовое бронирование.",
|
||||
"icon_showcase": "Витрина иконок",
|
||||
"icons_showcase": "Витрина иконок",
|
||||
"feature_currently_disabled": "Функция в данный момент отключена",
|
||||
"choose_an_option": "Выберите вариант",
|
||||
"enter_option_value": "Введите значение варианта",
|
||||
"remove_option": "Удалить вариант",
|
||||
"managed_users": "Управляемые пользователи",
|
||||
"managed_users_description": "Просмотр всех управляемых пользователей, созданных вашим OAuth-клиентом",
|
||||
"select_oAuth_client": "Выберите OAuth-клиент",
|
||||
"on_every_instance": "На каждом экземпляре",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Добавьте строки выше ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Umožňuje rezervujúcim dohodnúť stretnutia kedykoľvek je hostiteľ k dispozícii. Použite túto možnosť na maximalizáciu počtu potenciálnych stretnutí a v prípadoch, keď rovnomerná distribúcia stretnutí medzi hostiteľmi nie je až taká dôležitá.",
|
||||
"rr_distribution_method_balanced_title": "Vyvažovanie záťaže",
|
||||
"rr_distribution_method_balanced_description": "Budeme sledovať počet rezervácií u každého hostiteľa a porovnávať ich s ostatnými. Hostiteľov, ktorí majú príliš veľa rezervácií, dočasne deaktivujeme, aby boli stretnutia distribuované rovnomerne.",
|
||||
"edit_team_member_weights": "Upraviť váhy",
|
||||
"weights_updated_successfully": "Váhy boli úspešne aktualizované",
|
||||
"require_confirmation_for_free_email": "Vyžadovať potvrdenie len pre poskytovateľov bezplatných e-mailov (napr. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Vylúčiť e-maily, ktoré obsahujú...",
|
||||
"require_emails_that_contain": "Vyžadovať e-maily, ktoré obsahujú ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Robíte testovaciu rezerváciu.",
|
||||
"icon_showcase": "Ukážka ikony",
|
||||
"icons_showcase": "Ukážka ikon",
|
||||
"feature_currently_disabled": "Funkcia je momentálne deaktivovaná",
|
||||
"choose_an_option": "Vyberte možnosť",
|
||||
"enter_option_value": "Zadajte hodnotu možnosti",
|
||||
"remove_option": "Odstrániť možnosť",
|
||||
"managed_users": "Spravovaní používatelia",
|
||||
"managed_users_description": "Zobraziť všetkých spravovaných používateľov vytvorených vaším OAuth klientom",
|
||||
"select_oAuth_client": "Vyberte OAuth klienta",
|
||||
"on_every_instance": "Pri každej inštancii",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Pridajte svoje nové reťazce nad túto líniu ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Omogućava zakazivanje sastanaka kad god je domaćin dostupan. Koristite ovo da maksimalno povećate broj potencijalnih sastanaka kada je ravnomerna distribucija sastanaka među domaćinima manje važna.",
|
||||
"rr_distribution_method_balanced_title": "Balansiranje opterećenja",
|
||||
"rr_distribution_method_balanced_description": "Pratićemo broj zakazanih sastanaka kod svakog domaćina i upoređivati ga sa ostalima, privremeno onemogućavajući domaćine koji imaju previše sastanaka kako bi distribucija bila ravnomerna.",
|
||||
"edit_team_member_weights": "Izmeni težine",
|
||||
"weights_updated_successfully": "Težine su uspešno ažurirane",
|
||||
"require_confirmation_for_free_email": "Zahtevaj potvrdu samo za besplatne email provajdere (npr. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Isključi e-poruke koje sadrže ...",
|
||||
"require_emails_that_contain": "Zahtevaj email adrese koje sadrže...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Pravite probnu rezervaciju.",
|
||||
"icon_showcase": "Prikaz ikonica",
|
||||
"icons_showcase": "Prikaz ikonica",
|
||||
"feature_currently_disabled": "Funkcija je trenutno onemogućena",
|
||||
"choose_an_option": "Izaberite opciju",
|
||||
"enter_option_value": "Unesite vrednost opcije",
|
||||
"remove_option": "Ukloni opciju",
|
||||
"managed_users": "Upravljani korisnici",
|
||||
"managed_users_description": "Pogledajte sve upravljane korisnike koje je kreirao vaš OAuth klijent",
|
||||
"select_oAuth_client": "Izaberite OAuth klijenta",
|
||||
"on_every_instance": "Na svakoj instanci",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Dodajte svoje nove stringove iznad ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Låter bokare boka möten när en värd är tillgänglig. Använd detta för att maximera antalet potentiella möten som kan bokas och när jämn fördelning av möten mellan värdar är mindre viktigt.",
|
||||
"rr_distribution_method_balanced_title": "Lastbalansering",
|
||||
"rr_distribution_method_balanced_description": "Vi övervakar hur många bokningar som har gjorts med varje värd och jämför detta med andra, och inaktiverar vissa värdar som ligger för långt före så att bokningarna fördelas jämnt.",
|
||||
"edit_team_member_weights": "Redigera vikter",
|
||||
"weights_updated_successfully": "Vikterna har uppdaterats",
|
||||
"require_confirmation_for_free_email": "Kräv endast bekräftelse för leverantörer av gratise-post (t.ex. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Uteslut e-postmeddelanden som innehåller ...",
|
||||
"require_emails_that_contain": "Kräv e-postadresser som innehåller ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Du gör en testbokning.",
|
||||
"icon_showcase": "Ikonvisning",
|
||||
"icons_showcase": "Ikonvisning",
|
||||
"feature_currently_disabled": "Funktionen är för närvarande inaktiverad",
|
||||
"choose_an_option": "Välj ett alternativ",
|
||||
"enter_option_value": "Ange alternativets värde",
|
||||
"remove_option": "Ta bort alternativ",
|
||||
"managed_users": "Hanterade användare",
|
||||
"managed_users_description": "Se alla hanterade användare som skapats av din OAuth-klient",
|
||||
"select_oAuth_client": "Välj OAuth-klient",
|
||||
"on_every_instance": "På varje instans",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Rezervasyon yapanların, bir ev sahibi müsait olduğunda toplantı ayarlamasına olanak tanır. Potansiyel toplantı rezervasyonlarının sayısını en üst düzeye çıkarmak ve ev sahipleri arasında toplantıların eşit dağılımının daha az önemli olduğu durumlarda bunu kullanın.",
|
||||
"rr_distribution_method_balanced_title": "Yük dengeleme",
|
||||
"rr_distribution_method_balanced_description": "Her ev sahibiyle yapılan rezervasyon sayısını takip edip diğerleriyle karşılaştıracağız ve rezervasyonların eşit dağılımını sağlamak için çok ileri giden bazı ev sahiplerini devre dışı bırakacağız.",
|
||||
"edit_team_member_weights": "Ağırlıkları düzenle",
|
||||
"weights_updated_successfully": "Ağırlıklar başarıyla güncellendi",
|
||||
"require_confirmation_for_free_email": "Sadece ücretsiz e-posta sağlayıcıları için onay iste (Örn. @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "... içeren e-postaları hariç tut",
|
||||
"require_emails_that_contain": "E-postaların içermesi gereken ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Test rezervasyonu yapıyorsunuz.",
|
||||
"icon_showcase": "İkon vitrini",
|
||||
"icons_showcase": "İkonlar vitrini",
|
||||
"feature_currently_disabled": "Özellik şu anda devre dışı",
|
||||
"choose_an_option": "Bir seçenek belirleyin",
|
||||
"enter_option_value": "Seçenek değerini girin",
|
||||
"remove_option": "Seçeneği kaldır",
|
||||
"managed_users": "Yönetilen kullanıcılar",
|
||||
"managed_users_description": "OAuth istemciniz tarafından oluşturulan tüm yönetilen kullanıcıları görün",
|
||||
"select_oAuth_client": "OAuth istemcisi seçin",
|
||||
"on_every_instance": "Her örnekte",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Yeni dizelerinizi yukarıya ekleyin ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Дозволяє учасникам бронювати зустрічі, коли хост доступний. Використовуйте це для максимізації кількості потенційних зустрічей та коли рівномірний розподіл зустрічей між хостами менш важливий.",
|
||||
"rr_distribution_method_balanced_title": "Балансування навантаження",
|
||||
"rr_distribution_method_balanced_description": "Ми будемо відстежувати кількість бронювань для кожного хоста та порівнювати їх з іншими, деактивуючи тих хостів, які значно випереджають інших, щоб бронювання розподілялися рівномірно.",
|
||||
"edit_team_member_weights": "Редагувати ваги",
|
||||
"weights_updated_successfully": "Ваги успішно оновлено",
|
||||
"require_confirmation_for_free_email": "Вимагати підтвердження лише для безкоштовних поштових служб (наприклад, @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Виключити електронні адреси, які містять ...",
|
||||
"require_emails_that_contain": "Вимагати електронні адреси, що містять...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Ви робите тестове бронювання.",
|
||||
"icon_showcase": "Галерея іконок",
|
||||
"icons_showcase": "Галерея іконок",
|
||||
"feature_currently_disabled": "Функцію наразі вимкнено",
|
||||
"choose_an_option": "Оберіть опцію",
|
||||
"enter_option_value": "Введіть значення опції",
|
||||
"remove_option": "Видалити опцію",
|
||||
"managed_users": "Керовані користувачі",
|
||||
"managed_users_description": "Переглянути всіх керованих користувачів, створених вашим OAuth-клієнтом",
|
||||
"select_oAuth_client": "Оберіть OAuth-клієнта",
|
||||
"on_every_instance": "На кожному екземплярі",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "Cho phép người đặt lịch đặt cuộc họp bất cứ khi nào người chủ trì có mặt. Sử dụng tính năng này để tối đa hóa số lượng cuộc họp tiềm năng được đặt và khi việc phân phối cuộc họp đồng đều giữa các chủ trì ít quan trọng hơn.",
|
||||
"rr_distribution_method_balanced_title": "Cân bằng tải",
|
||||
"rr_distribution_method_balanced_description": "Chúng tôi sẽ theo dõi số lượng đặt lịch đã được thực hiện với từng chủ trì và so sánh với những người khác, vô hiệu hóa một số chủ trì đã nhận quá nhiều lịch để đảm bảo việc đặt lịch được phân phối đồng đều.",
|
||||
"edit_team_member_weights": "Chỉnh sửa trọng số",
|
||||
"weights_updated_successfully": "Đã cập nhật trọng số thành công",
|
||||
"require_confirmation_for_free_email": "Chỉ yêu cầu xác nhận đối với các nhà cung cấp email miễn phí (Ví dụ: @gmail.com, @outlook.com)",
|
||||
"exclude_emails_that_contain": "Loại trừ các email chứa ...",
|
||||
"require_emails_that_contain": "Yêu cầu email phải chứa ...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "Bạn đang thực hiện đặt lịch thử nghiệm.",
|
||||
"icon_showcase": "Trưng bày biểu tượng",
|
||||
"icons_showcase": "Trưng bày các biểu tượng",
|
||||
"feature_currently_disabled": "Tính năng hiện đang bị vô hiệu hóa",
|
||||
"choose_an_option": "Chọn một tùy chọn",
|
||||
"enter_option_value": "Nhập giá trị tùy chọn",
|
||||
"remove_option": "Xóa tùy chọn",
|
||||
"managed_users": "Người dùng được quản lý",
|
||||
"managed_users_description": "Xem tất cả người dùng được quản lý được tạo bởi OAuth client của bạn",
|
||||
"select_oAuth_client": "Chọn OAuth Client",
|
||||
"on_every_instance": "Trên mỗi phiên bản",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "允许预订者在任何主持人可用时预订会议。当会议在主持人之间的均衡分配不太重要时,可使用此选项来最大化潜在会议预订数量。",
|
||||
"rr_distribution_method_balanced_title": "负载均衡",
|
||||
"rr_distribution_method_balanced_description": "系统会监控每位主持人已接受的预订数量并与其他人进行比较,如果某些主持人的预订数量远超他人,系统会暂时停用这些主持人,以确保预订均匀分配。",
|
||||
"edit_team_member_weights": "编辑权重",
|
||||
"weights_updated_successfully": "权重更新成功",
|
||||
"require_confirmation_for_free_email": "仅对免费邮箱提供商要求确认(例如 @gmail.com、@outlook.com)",
|
||||
"exclude_emails_that_contain": "排除包含...的电子邮件",
|
||||
"require_emails_that_contain": "要求电子邮件包含...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "您正在进行测试预订。",
|
||||
"icon_showcase": "图标展示",
|
||||
"icons_showcase": "图标展示",
|
||||
"feature_currently_disabled": "该功能当前已禁用",
|
||||
"choose_an_option": "选择一个选项",
|
||||
"enter_option_value": "输入选项值",
|
||||
"remove_option": "删除选项",
|
||||
"managed_users": "托管用户",
|
||||
"managed_users_description": "查看由您的 OAuth 客户端创建的所有托管用户",
|
||||
"select_oAuth_client": "选择 OAuth 客户端",
|
||||
"on_every_instance": "在每个实例上",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 在此上方添加您的新字符串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -2874,6 +2874,8 @@
|
||||
"rr_distribution_method_availability_description": "讓預約者可以在任何主持人有空的時候預約會議。當會議在主持人之間的平均分配不是那麼重要時,可使用此選項來最大化潛在會議預約數量。",
|
||||
"rr_distribution_method_balanced_title": "負載平衡",
|
||||
"rr_distribution_method_balanced_description": "系統會監控每位主持人的預約數量並與其他人進行比較,當某些主持人的預約量遠超過其他人時,系統會暫時停用這些主持人,以確保預約能夠均勻分配。",
|
||||
"edit_team_member_weights": "編輯權重",
|
||||
"weights_updated_successfully": "權重更新成功",
|
||||
"require_confirmation_for_free_email": "僅對免費電子郵件供應商要求確認(例如 @gmail.com、@outlook.com)",
|
||||
"exclude_emails_that_contain": "排除包含...的電子郵件",
|
||||
"require_emails_that_contain": "要求電子郵件包含...",
|
||||
@@ -2917,11 +2919,13 @@
|
||||
"dry_run_mode_active": "您正在進行測試預約。",
|
||||
"icon_showcase": "圖示展示",
|
||||
"icons_showcase": "圖示展示",
|
||||
"feature_currently_disabled": "此功能目前已停用",
|
||||
"choose_an_option": "選擇一個選項",
|
||||
"enter_option_value": "輸入選項值",
|
||||
"remove_option": "移除選項",
|
||||
"managed_users": "受管理使用者",
|
||||
"managed_users_description": "查看由您的 OAuth 用戶端建立的所有受管理使用者",
|
||||
"select_oAuth_client": "選擇 OAuth 用戶端",
|
||||
"on_every_instance": "在每個執行個體上",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 請在此處新增您的字串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { DehydratedState } from "@tanstack/react-query";
|
||||
import type { EmbedProps } from "app/WithEmbedSSR";
|
||||
import type { GetServerSideProps } from "next";
|
||||
import { encode } from "querystring";
|
||||
import type { z } from "zod";
|
||||
@@ -18,7 +19,6 @@ import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
import type { UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
import { getTemporaryOrgRedirect } from "@lib/getTemporaryOrgRedirect";
|
||||
import type { EmbedProps } from "app/WithEmbedSSR";
|
||||
|
||||
import { ssrInit } from "@server/lib/ssr";
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ describe("pagesAndRewritePaths", () => {
|
||||
"video",
|
||||
"workflows",
|
||||
"403",
|
||||
"404",
|
||||
"500",
|
||||
"bookings",
|
||||
"event-types",
|
||||
|
||||
@@ -2389,6 +2389,8 @@
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"minimum": 1,
|
||||
"maximum": 1000,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -2399,6 +2401,7 @@
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -2581,6 +2584,28 @@
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their start time in ascending or descending order.",
|
||||
"example": "?sortStart=asc OR ?sortStart=desc",
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortEnd",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their end time in ascending or descending order.",
|
||||
"example": "?sortEnd=asc OR ?sortEnd=desc",
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -2681,6 +2706,80 @@
|
||||
"tags": ["Orgs / Users / OOO"]
|
||||
}
|
||||
},
|
||||
"/v2/organizations/{orgId}/ooo": {
|
||||
"get": {
|
||||
"operationId": "OrganizationsUsersOOOController_getOrganizationUsersOOO",
|
||||
"summary": "Get all OOO entries of org users",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "orgId",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "The number of items to return",
|
||||
"example": 10,
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "skip",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "The number of items to skip",
|
||||
"example": 0,
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their start time in ascending or descending order.",
|
||||
"example": "?sortStart=asc OR ?sortStart=desc",
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortEnd",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their end time in ascending or descending order.",
|
||||
"example": "?sortEnd=asc OR ?sortEnd=desc",
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter ooo entries by the user email address. user must be within your organization.",
|
||||
"example": "example@domain.com",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"tags": ["Orgs / Users / OOO"]
|
||||
}
|
||||
},
|
||||
"/v2/organizations/{orgId}/webhooks": {
|
||||
"get": {
|
||||
"operationId": "OrganizationsWebhooksController_getAllOrganizationWebhooks",
|
||||
@@ -7312,7 +7411,7 @@
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "name",
|
||||
"description": "only allowed value for type is `name`"
|
||||
"description": "only allowed value for type is `name`. Used for having 1 booking field for both first name and last name."
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
@@ -8038,7 +8137,7 @@
|
||||
"boolean"
|
||||
],
|
||||
"example": "name",
|
||||
"description": "only allowed value for type is `name`",
|
||||
"description": "only allowed value for type is `name`. Used for having 1 booking field for both first name and last name.",
|
||||
"default": "name"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@@ -15,7 +15,7 @@ Once your account is created, the next step is to create an OAuth client. This a
|
||||
2. Add an OAuth client.
|
||||
1. Name: anything is fine. You can use your company name or your website.
|
||||
2. Redirect URIs: Used to validate origin of requests - your website's URLs from which atoms are allowed to make requests to our API. Supports wildcard syntax where "*" would support any origin, and "*app.com" would support "example.app.com", and "https//example.com*" where it would support any origin from that domain.
|
||||
3. Booking, reschedule and cancel URLs: URLs of pages where users land after a successful booking or if they want to reschedule or cancel a booking. We will pass information in the URL when redirecting to your pages and you will use our hooks and components to implement the pages. See [this guide](/platform/booking-redirects).
|
||||
3. Booking, reschedule and cancel URLs: URLs of pages where users land after a successful booking or if they want to reschedule or cancel a booking. We will pass information in the URL when redirecting to your pages and you will use our hooks and components to implement the pages. See [this guide](/platform/guides/booking-redirects).
|
||||
4. Permissions - most likely you need all enabled:
|
||||
1. Event type: event type is a user event that others can book. For example, Alice is a language teacher and she has an event type “30 minutes Italian lesson” that others can then book.
|
||||
2. Booking: When Bob books the Italian lesson, a booking is created and shows up on the calendar that Alice connected using atoms.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-next": "14.0.4",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
|
||||
+130
-164
@@ -44,169 +44,135 @@
|
||||
"icon": "github",
|
||||
"url": "https://github.com/calcom/cal.com"
|
||||
},
|
||||
"feedback": {
|
||||
"thumbsRating": true,
|
||||
"suggestEdit": true
|
||||
},
|
||||
"modeToggle": {
|
||||
"default": "light",
|
||||
"isHidden": true
|
||||
},
|
||||
"topbarCtaButton": {
|
||||
"name": "Login",
|
||||
"url": "https://app.cal.com/auth/login"
|
||||
},
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Developer",
|
||||
"icon": "code",
|
||||
"url": "https://cal.com/docs"
|
||||
},
|
||||
{
|
||||
"name": "GitHub",
|
||||
"icon": "github",
|
||||
"url": "https://github.com/calcom/cal.com"
|
||||
},
|
||||
{
|
||||
"name": "Blog",
|
||||
"icon": "newspaper",
|
||||
"url": "https://cal.com/blog"
|
||||
}
|
||||
],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Documentation",
|
||||
"pages": [
|
||||
"welcome",
|
||||
{
|
||||
"group": "Quick Start",
|
||||
"icon": "play",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"quick-start/quickstart",
|
||||
"quick-start/sign-up",
|
||||
"quick-start/complete-onboarding",
|
||||
"quick-start/customization",
|
||||
"quick-start/calendar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Event Types",
|
||||
"icon": "calendar",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"event-types/event-types",
|
||||
"event-types/booking-questions",
|
||||
"event-types/add-events",
|
||||
"event-types/managed-events",
|
||||
"event-types/adding-zoom",
|
||||
"event-types/booking-frequency",
|
||||
"event-types/round-robin",
|
||||
"event-types/dynamic",
|
||||
"event-types/collective-events",
|
||||
"event-types/create-first-event",
|
||||
"event-types/create-recurring",
|
||||
"event-types/create-secret",
|
||||
"event-types/custom-name",
|
||||
"event-types/custom-time-slots",
|
||||
"event-types/disable-confirmation",
|
||||
"event-types/disable-guests",
|
||||
"event-types/display-issues",
|
||||
"event-types/dynamic",
|
||||
"event-types/event-buffer",
|
||||
"event-types/hide-notes",
|
||||
"event-types/how-to-add-location",
|
||||
"event-types/how-to-receive-payments",
|
||||
"event-types/how-to-requires",
|
||||
"event-types/how-to-set-buffer",
|
||||
"event-types/how-to-time-slot-intervals",
|
||||
"event-types/limit-future-bookings",
|
||||
"event-types/location-of-event",
|
||||
"event-types/min-notice",
|
||||
"event-types/multiple-durations",
|
||||
"event-types/offer-seats",
|
||||
"event-types/recurring-events",
|
||||
"event-types/require-criteria",
|
||||
"event-types/secret-events",
|
||||
"event-types/setup-location",
|
||||
"event-types/single-use",
|
||||
"event-types/split-name",
|
||||
"event-types/sponsor",
|
||||
"event-types/symbolic-issues"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Availabilities",
|
||||
"icon": "magnifying-glass",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"availabilities/date-overrides",
|
||||
"availabilities/multiple-schedules",
|
||||
"availabilities/multiple-slots"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Bookings",
|
||||
"icon": "calendar-check",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"bookings/no-show",
|
||||
"bookings/paid-bookings",
|
||||
"bookings/prefill-fields"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Embedding",
|
||||
"icon": "code",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"embedding/adding-embed",
|
||||
"embedding/adding-slots",
|
||||
"embedding/embed-events",
|
||||
"embedding/embed-instructions",
|
||||
"embedding/embed-snippet-generator",
|
||||
"embedding/prefill-booking-form-embed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Auth and Provisioning",
|
||||
"icon": "user-lock",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"auth-and-provision/scim-okta",
|
||||
"auth-and-provision/oidc-with-okta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Apps and Integrations",
|
||||
"icon": "code-branch",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"apps-and-integrations/apps",
|
||||
"apps-and-integrations/app-store",
|
||||
"apps-and-integrations/adding-first-app",
|
||||
"apps-and-integrations/assign-people",
|
||||
"apps-and-integrations/build-greeter-app",
|
||||
"apps-and-integrations/how-to-build-an-app",
|
||||
"apps-and-integrations/syncing-third-party"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Developers",
|
||||
"icon": "terminal",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"apps-and-integrations/oauth",
|
||||
"apps-and-integrations/open-source",
|
||||
"webhooks"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"x": "https://x.com/calcom",
|
||||
"github": "https://github.com/calcom",
|
||||
"linkedin": "https://www.linkedin.com/company/cal-com"
|
||||
{
|
||||
"name": "Blog",
|
||||
"icon": "newspaper",
|
||||
"url": "https://cal.com/blog"
|
||||
}
|
||||
],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Documentation",
|
||||
"pages": [
|
||||
"welcome",
|
||||
{
|
||||
"group": "Quick Start",
|
||||
"icon": "play",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"quick-start/quickstart",
|
||||
"quick-start/sign-up",
|
||||
"quick-start/complete-onboarding",
|
||||
"quick-start/customization",
|
||||
"quick-start/calendar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Event Types",
|
||||
"icon": "calendar",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"event-types/event-types",
|
||||
"event-types/booking-questions",
|
||||
"event-types/add-events",
|
||||
"event-types/managed-events",
|
||||
"event-types/adding-zoom",
|
||||
"event-types/booking-frequency",
|
||||
"event-types/round-robin",
|
||||
"event-types/dynamic",
|
||||
"event-types/collective-events",
|
||||
"event-types/create-first-event",
|
||||
"event-types/create-recurring",
|
||||
"event-types/create-secret",
|
||||
"event-types/custom-name",
|
||||
"event-types/custom-time-slots",
|
||||
"event-types/disable-confirmation",
|
||||
"event-types/disable-guests",
|
||||
"event-types/display-issues",
|
||||
"event-types/dynamic",
|
||||
"event-types/event-buffer",
|
||||
"event-types/hide-notes",
|
||||
"event-types/how-to-add-location",
|
||||
"event-types/how-to-receive-payments",
|
||||
"event-types/how-to-requires",
|
||||
"event-types/how-to-set-buffer",
|
||||
"event-types/how-to-time-slot-intervals",
|
||||
"event-types/limit-future-bookings",
|
||||
"event-types/location-of-event",
|
||||
"event-types/min-notice",
|
||||
"event-types/multiple-durations",
|
||||
"event-types/offer-seats",
|
||||
"event-types/recurring-events",
|
||||
"event-types/require-criteria",
|
||||
"event-types/secret-events",
|
||||
"event-types/setup-location",
|
||||
"event-types/single-use",
|
||||
"event-types/split-name",
|
||||
"event-types/sponsor",
|
||||
"event-types/symbolic-issues"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Availabilities",
|
||||
"icon": "magnifying-glass",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"availabilities/date-overrides",
|
||||
"availabilities/multiple-schedules",
|
||||
"availabilities/multiple-slots"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Bookings",
|
||||
"icon": "calendar-check",
|
||||
"iconType": "solid",
|
||||
"pages": ["bookings/no-show", "bookings/paid-bookings", "bookings/prefill-fields"]
|
||||
},
|
||||
{
|
||||
"group": "Embedding",
|
||||
"icon": "code",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"embedding/adding-embed",
|
||||
"embedding/adding-slots",
|
||||
"embedding/embed-events",
|
||||
"embedding/embed-instructions",
|
||||
"embedding/embed-snippet-generator",
|
||||
"embedding/prefill-booking-form-embed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Auth and Provisioning",
|
||||
"icon": "user-lock",
|
||||
"iconType": "solid",
|
||||
"pages": ["auth-and-provision/scim-okta", "auth-and-provision/oidc-with-okta"]
|
||||
},
|
||||
{
|
||||
"group": "Apps and Integrations",
|
||||
"icon": "code-branch",
|
||||
"iconType": "solid",
|
||||
"pages": [
|
||||
"apps-and-integrations/apps",
|
||||
"apps-and-integrations/app-store",
|
||||
"apps-and-integrations/adding-first-app",
|
||||
"apps-and-integrations/assign-people",
|
||||
"apps-and-integrations/build-greeter-app",
|
||||
"apps-and-integrations/how-to-build-an-app",
|
||||
"apps-and-integrations/syncing-third-party"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Developers",
|
||||
"icon": "terminal",
|
||||
"iconType": "solid",
|
||||
"pages": ["apps-and-integrations/oauth", "apps-and-integrations/open-source", "webhooks"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"x": "https://x.com/calcom",
|
||||
"github": "https://github.com/calcom",
|
||||
"linkedin": "https://www.linkedin.com/company/cal-com"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2876,6 +2876,8 @@ checksums:
|
||||
rr_distribution_method_availability_description: 0fc05c527e1307e0c20165f0cefe2ed4
|
||||
rr_distribution_method_balanced_title: f13fe5c1c5e35ad5b2e0139df5c3e62f
|
||||
rr_distribution_method_balanced_description: 23fd5a95ac9d9f6283883180ba30db32
|
||||
edit_team_member_weights: 66ba6fc048187689fc71b00be1d1ca0f
|
||||
weights_updated_successfully: e5ad5ff71665572c8512f1cb4112359c
|
||||
require_confirmation_for_free_email: 669a3c050cc065e85df79e0e7f12bbfd
|
||||
exclude_emails_that_contain: d43255c873c75c8fe1adcb8f8b7af914
|
||||
require_emails_that_contain: 54623674a8bf704fd44299c59eb31363
|
||||
@@ -2919,10 +2921,12 @@ checksums:
|
||||
dry_run_mode_active: 921ba1004a593504ba9719886864d90e
|
||||
icon_showcase: 0879657c77461a19cafbdaa1e168b95e
|
||||
icons_showcase: 8771aa0011d8ffefbe9370312152ef6a
|
||||
feature_currently_disabled: 3d4991fb6097adb96e8e2afca1e44b7e
|
||||
choose_an_option: 1c57b133afef47a60666d5d37b9b321e
|
||||
enter_option_value: 03bdf1e9fd1bdba6f895bf6f85d2fd28
|
||||
remove_option: 42e52c46cc51e56ebb5540bfb6f19b95
|
||||
managed_users: c6db1c3bb5c9b451471ca9b8d7dc8366
|
||||
managed_users_description: 45fea5321847b0c8ee72ce33684c1283
|
||||
select_oAuth_client: 0ebdcf296c0f68eca626cdb153204607
|
||||
on_every_instance: db0e9e92055a38572fffa40f44440035
|
||||
ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS: 18323f2f3fabb169a7cb50ff62433850
|
||||
|
||||
Binary file not shown.
@@ -87,8 +87,7 @@ export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => {
|
||||
<p className="text-sm">Click or scan the invoice below to pay</p>
|
||||
<Link
|
||||
href={`lightning:${paymentRequest}`}
|
||||
className="inline-flex items-center justify-center rounded-2xl rounded-md border border-transparent p-2 bg-white
|
||||
font-medium text-black shadow-sm hover:brightness-95 focus:outline-none focus:ring-offset-2 p-2">
|
||||
className="inline-flex items-center justify-center rounded-2xl rounded-md border border-transparent bg-white p-2 font-medium text-black shadow-sm hover:brightness-95 focus:outline-none focus:ring-offset-2">
|
||||
<QRCode size={192} value={paymentRequest} />
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import ga4_config_json from "./ga4/config.json";
|
||||
import { metadata as giphy__metadata_ts } from "./giphy/_metadata";
|
||||
import { metadata as googlecalendar__metadata_ts } from "./googlecalendar/_metadata";
|
||||
import { metadata as googlevideo__metadata_ts } from "./googlevideo/_metadata";
|
||||
import granola_config_json from "./granola/config.json";
|
||||
import gtm_config_json from "./gtm/config.json";
|
||||
import horizon_workrooms_config_json from "./horizon-workrooms/config.json";
|
||||
import { metadata as hubspot__metadata_ts } from "./hubspot/_metadata";
|
||||
@@ -135,6 +136,7 @@ export const appStoreMetadata = {
|
||||
giphy: giphy__metadata_ts,
|
||||
googlecalendar: googlecalendar__metadata_ts,
|
||||
googlevideo: googlevideo__metadata_ts,
|
||||
granola: granola_config_json,
|
||||
gtm: gtm_config_json,
|
||||
"horizon-workrooms": horizon_workrooms_config_json,
|
||||
hubspot: hubspot__metadata_ts,
|
||||
|
||||
@@ -34,6 +34,7 @@ export const apiHandlers = {
|
||||
giphy: import("./giphy/api"),
|
||||
googlecalendar: import("./googlecalendar/api"),
|
||||
googlevideo: import("./googlevideo/api"),
|
||||
granola: import("./granola/api"),
|
||||
gtm: import("./gtm/api"),
|
||||
"horizon-workrooms": import("./horizon-workrooms/api"),
|
||||
hubspot: import("./hubspot/api"),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user