Compare commits

..
53 Commits
Author SHA1 Message Date
Keith Williams 343e2ac9d7 chore: v4.5.10 (#17001)
release.yml / release (push) Canceled after 0s
2024-10-08 16:59:25 -03:00
Benny Joo 670b82fd23 fix: add fallback to data needed in SettingsLayout (#17004) 2024-10-08 15:51:38 -04:00
Keith Williams e6f81d09c8 chore: Update PR template to account for new docs (#17003) 2024-10-08 15:35:23 -03:00
Benny Joo 8f91ffe692 Revert "remove pages router and use app router (#16793)" (#17002)
This reverts commit 664a92a1d0.
2024-10-08 15:00:43 -03:00
Benny Joo f5dbdae4a9 fix: Close OOO Create Modal on backdrop click (#17000) 2024-10-08 17:42:28 +00:00
Calcom BotandReplexica e99f6048d6 feat: update translations (#16999)
Co-authored-by: Replexica <support@replexica.com>
2024-10-08 23:08:47 +05:30
654a204878 feat: Attribute based routing from Team Routing Form to Team Event(with assigned users matching the attribute logic) (#16823)
* Initial commit

* routingForm to Booking a particular team member working

* Happy path working

* Fixes

* Fix router query params forwarding

* Add basicConfig within app

* Tests

* More tests

* Update packages/app-store/routing-forms/components/SingleForm.tsx

Co-authored-by: Omar López <zomars@me.com>

---------

Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-10-08 21:12:32 +05:30
Syed Ali Shahbaz 7928933852 fixes (#16990) 2024-10-08 15:36:16 +00:00
Lauris SkraucisandMorgan Vernay c4cdba1015 refactor: throttler rate limits for oauth client & access token (#16962)
Co-authored-by: Morgan Vernay <morgan@cal.com>
2024-10-08 17:34:41 +03:00
Benny Joo 5ed36a7fe1 chore: remove react code in getLayout (#16997)
* chore: no need to pass title, description in getLayout

* acutally, we do
2024-10-08 14:22:26 +00:00
Joe Au-YeungandBenny Joo e77a2f6963 fix: Salesforce assign event to organizer (#16971)
* Refactor get SF user and create event

* address code nit

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-10-08 14:06:51 +00:00
Lauris Skraucis a10d3599e2 refactor: platform bookings hooks & bookings API (#16963)
* chore: delete unused bookings hook

* refactor: group bookings hooks in folder

* refactor: rename useGetBooking, useGetBookings to useBooking, useBookings

* refactor: booking inputs and outputs

* chore: make bookings controller work with new inputs and outputs

* make examples app work

* refactor: deprecate fields instead of removing them

* readd eventtypeid

* swagger regenerate

* make recurring booking backwards compatible

* fix test

* update changelog

* swagger update

* fix import

* chore: update lock file
2024-10-08 14:05:28 +02:00
Alex van Andel d99f171597 perf: Only render the TimezoneChangeDialog when needed (#16986)
* perf: Only render the TimezoneChangeDialog when needed

* fix: Import error

* Minor style fixes
2024-10-08 10:41:53 +01:00
Syed Ali ShahbazandKeith Williams da55306a5a chore: add dev docs on mintlify (#16935)
* --init

* progress...

* add more docs

* bunch of changes and added back platform

* development guides added

* more guides in develop with cal

* self hosted WIP

* deployments

* fix deployment steps

* self-hosted guides

* ..

* Removed the development only sections

* Removed 'with Cal.com'

* use steps component for steps

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-10-08 02:32:16 -03:00
Benny Joo 66378160df chore: remove log (#16981) 2024-10-07 22:10:25 +00:00
Anik Dhabal Babu 8aee8d9d3b fix: SMS reminders are being sent out with an HTML code (#16966) 2024-10-07 17:51:04 -04:00
Calcom BotandReplexica 79e33a4d26 feat: update translations (#16972)
Co-authored-by: Replexica <support@replexica.com>
2024-10-07 15:37:32 -03:00
Carina WollendorferandCarinaWolli b5fa43f086 feat: checkbox to count managed events for team-wide limits (#16923)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2024-10-07 11:36:50 -04:00
Joe Au-Yeung 0d757039f7 chore: Fixing ICS file in workflows & ICS calendar descriptions [CAL-4409] (#16731)
* Remove title and subtitle from ICS calendar description

* Remove unused method

* Use generateIcsString function for workflows

* Type fixes

* Refactor typing of CalEventParser

* WIP

* Type fixes

* Fix test

* Fix tests

* type fixes

* Remove duplicate code before `scheduleEmailReminder`
2024-10-07 10:50:50 -04:00
Lauris Skraucis 44f6f2e320 refactor: v2 throttler guard (#16922)
* chore: add logs

* refactor: replace deprecated redis.setex with redis.set

* chore: log response headers
2024-10-07 11:02:41 +00:00
Benny Joo d8eb1df61d fix: add suppressHydrationWarning to app router layout (#16960) 2024-10-07 12:40:09 +02:00
Lauris Skraucis ef7cac6c50 fix: booker atom phone booking field (#16945)
* fix: booker atom phone booking field

* chore: show usual booker in examples app

* refactor: import styles file manually
2024-10-07 12:39:54 +02:00
Benny Joo 21dd44733f fix: make theme logic safe and add better e2e tests (#16959)
* fix: improve theme logic

* remove null from ThemeLabelProps value

* add better e2e tests
2024-10-07 11:23:30 +01:00
Lauris Skraucis b0bfec7247 feat: Booker atom read only fields (#16904)
* refactor: include user-readonly in BookingFields

* feat: add read only name and email booking fields

* feat: Booker atom prop for read only name and email

* refactor: simplify props type
2024-10-07 15:03:07 +05:30
Lauris Skraucis ba5b9e951a feat: Booker atom enable hiding event details (#16906)
* refactor: Booker component hideEventTypeDetails hides sidebar

* feat: Booker atom hideEventTypeDetails prop

* fix: redundant border appearing if event details hidden

* Revert "fix: redundant border appearing if event details hidden"

This reverts commit 63122a906a8e41b54074387e1a6a4f0e4489a8a9.

* fix: border
2024-10-07 09:52:47 +02:00
Lauris Skraucis 5e3865b645 docs: v2 mintlify update (#16961) 2024-10-07 06:54:36 +00:00
Rajiv Sahal a02240b579 fix: add missing ApiOperation tag v2 (#16947)
* add missing api operation tag

* update openapi spec for docs
2024-10-06 20:04:25 -03:00
Benny Joo 376caa412d fix: DOM attribute warning in event-types edit page (#16953) 2024-10-05 03:39:11 +00:00
Benny Joo 8722745185 chore: improve readability of some tests (#16954) 2024-10-05 08:49:29 +05:30
+12 a4a3eb5ea9 refactor: Billing service (#15366)
* WIP: Billing service

* WIP

* Update __handler.ts

* Update index.ts

* WIP

* WIP

Signed-off-by: zomars <zomars@me.com>

* WIP

Signed-off-by: zomars <zomars@me.com>

* Update delete.handler.ts

* Update delete.handler.ts

* Update internal-team-billing.ts

* WIP

* Type fixes

Signed-off-by: zomars <zomars@me.com>

* WIP

Signed-off-by: zomars <zomars@me.com>

* Discard changes to apps/api/v2/src/ee/event-types/event-types_2024_04_15/controllers/event-types.controller.ts

* Discard changes to packages/app-store/skype/config.json

* style: update text area (#15934)

* chore: update text-editor input

* chore: update text-editor input

* final update

* Update Editor.tsx

---------

Co-authored-by: unknown <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>

* fix: #15697 Assignment warning modal poping up ,even when hosts are added . (#15699)

* removed reduntand check on assignedusers

* update for managed eventtype

* formatted

* comments

* Updated comments

* extracted checkForEmptyAssignment and added tests

* updated comments

* updated to show dialog also when not yet saved

* update translations

* updated comments

* updated translation

* updated types

* chore: update naming and comments

* Delete apps/web/lib/checkForEmptyAssignment.ts

deleted since file was renamed

* Delete apps/web/test/lib/checkForEmptyAssignment.test.ts

deleted as the file is renamed to be more descriptive

* update to do teamcheck before

* chore: revert name to CheckForEmptyAssignment

* updated check conditions

* updated useEffect dependencies

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>

* fix: getting an error when a team member tries to leave (#15925)

a team

Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>

* feat: add transitions to more components (#15916)

* add transitions to more components

* chore: Remove duplicate class

* fix: Change minimum number of teams required for org self-serve (#15955)

* fix: Change minimum number of teams required for org self-serve

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Use a new constant for displaying org helper text dialogue

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* Update packages/lib/constants.ts

* Update turbo.json

---------

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* feat: pwa ready and add shortcut for quick access (#15957)

* chore: Update site.webmanifest with additional display properties

* chore: Update site.webmanifest with additional display properties

* Update apps/web/public/site.webmanifest

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* i18n: update translations for "by proceeding, ..." (#15921)

* feat: Add title attribute to iframe in embed.ts (#15944)

* feat: Add title attribute to iframe in embed.ts

* Update packages/embeds/embed-core/src/embed.ts

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* fix: Assignment reminder modal appears when deleting a team event type (#15544)

* fix: Assignment reminder modal appears when deleting a team event type

* update

* Update EventTypeSingleLayout.tsx

* Update event-types-single-view.tsx

* update

* Early return https://handbook.cal.com/engineering/best-practices/prefer-early-returns

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Hariom <hariombalhara@gmail.com>

* fix: Add CORP and COEP headers to embedded pages (#15275)

* Add CORP headers

* Improve test

* Add unit tests as well

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* feat: No-show bookings - do not count towards a member's round robin assignment (#15323)

* feat: No-show bookings - do not count towards a member's round robin assignment

* filter no show organizer

* remove logs

* fix: filter bookings where host attendee is no show

* fix: use not condition for noShow

* chore: test

* add default false for noShowHost

* Revert "chore: test"

This reverts commit c914a8fc4a14ca9c7d8c4a08ff8b0f463789171c.

* chore: integration test

* fix: noShowHost not working for null

* Update packages/lib/server/getLuckyUser.ts

* chore: update test description

---------

Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: gh0st91848 <gh0st91848@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* refactor: v1 orgs unlimited teams (#15908)

* refactor: v1 orgs unlimited teams

* fix: response message ownerId

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: refresh connect atoms on token change (#15933)

* added dropdown

* change comment

* fix: added types

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: Next.js bundle analysis (#15903)

* fix: Next.js bundle analysis

* Added the main checkout back

* fix: type in webhook payload (#15912)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* fix: auto accept (#15975)

* fix: auto accept

* Update packages/lib/server/repository/organization.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* fix: Broken GitHub workflows (#15979)

* test: Delete credential endpoint (#15322)

* Init

* Add mock trpc context

* Intro mockDatabaseClient

* Introduce mockDatabaseClient class

* Add delete video app test

* Add calendar test

* Remove unused func from bookingScenario

* Remove console.log

* Add app repository

* Add createMany method to event type repository

* Remove instance of MockDatabaseClient from video test

* Add destination calendar repository

* Remove instances of MockDatabaseClient

* abstract logic to own handler

* Remove dev dependency

* Clean up

* Type fix

* Pull yarn.lock from main

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>

* fix: #15967 Show better error when wrong variable is used in custom event name (#15974)

* update to show exact err msg with custom event name

* updated tests for validateCustomEventName

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>

* WIP

Signed-off-by: zomars <zomars@me.com>

* Update yarn.lock

* Update publish.handler.ts

* Update internal-team-billing.test.ts

* rename create to init

* remove sync services

* wip tests for delete team

* wip tets

* wip tests

* tests/internal-test

* remove return that is inaccessable

* remove team calls to use repository

* remove redudant file

* update team repo

* add stripe mocks and test

* fix constants

* tests to main stripe handler

* remove logs

* fix constants

* Update packages/features/ee/billing/api/webhook/_customer.subscription.deleted.team-plan.ts

Co-authored-by: Omar López <zomars@me.com>

* move workflow logic to a service

* use static method > creating new class

* fix: remove http code deep in repo + tests

* Feedback

* Update index.ts

* Type fix

* Lazy load fixes

---------

Signed-off-by: zomars <zomars@me.com>
Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>
Co-authored-by: Rohan Advani <122167726+RNAdvani@users.noreply.github.com>
Co-authored-by: unknown <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Vijay <vijayraghav22@gmail.com>
Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Hichem Fantar <hichemfantar2049@gmail.com>
Co-authored-by: Souptik Datta <souptikdatta2001@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Johannes Maendle <141119154+jomaendle2@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: gh0st91848 <gh0st91848@gmail.com>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: sean-brydon <sean@cal.com>
Co-authored-by: sean <sean@brydon.io>
2024-10-04 13:44:50 -07:00
Benny Joo b560475d89 fix: flaky one in local e2e test (#16949) 2024-10-04 20:36:52 +00:00
Calcom BotandReplexica 4872daef60 feat: update translations (#16943)
Co-authored-by: Replexica <support@replexica.com>
2024-10-04 20:15:18 +00:00
Anik Dhabal Babu dfa92f5cb6 fix: currency conversion error for paypal (#16917)
* fix: currency conversion error for paypal

* type-error
2024-10-05 01:11:09 +05:30
Benny Joo babb1a3bf7 fix annoying warning due to key spread (#16948) 2024-10-04 19:39:20 +00:00
Benny Joo 7b5a2726ab fix: translations for insights, routing-forms, apps store, etc (#16933)
* remove outdated translations for insights

* use i18n strings for insights

* use i18n strings for routing forms

* use i18n strings for apps store

* fix more pages

* refactor

* fix
2024-10-04 09:45:51 -03:00
sean-brydon 7d4653296e add trial days to stripe teams checkout (#16940) 2024-10-04 12:42:51 +00:00
Hariom Balhara 644fb38f87 test: more Embed Page Params filtering tests (#16937)
* Add rescheduleUid as config param scenario

* Restructure test buttons

* Use correct namespace as per rename
2024-10-04 12:01:59 +01:00
Ash Davis 743b155a88 fix: rescheduledBy to carry into success url redirect (#16931) 2024-10-04 10:59:52 +01:00
Benny JooandAlex van Andel 664a92a1d0 remove pages router and use app router (#16793)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2024-10-04 10:28:21 +01:00
Hariom Balhara 8ae71f6160 fix: Certain query params being filtered out from embed (#16936) 2024-10-04 12:59:45 +05:30
Omar López ab1eab9c54 chore: v4.5.9 (#16926)
release.yml / release (push) Canceled after 0s
2024-10-03 12:26:35 -07:00
MuhammadandAnik Dhabal Babu a64b7752c9 fix: Tooltip must be used within TooltipProvider (#16918)
* fixes #16833

* Update index.tsx

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2024-10-03 15:37:11 +00:00
Keith WilliamsandSyed Ali Shahbaz be728e9c01 feat: add Mintlify docs (#16787)
* feat: Add Mintlify docs

* Fixed the mint.json for v2

* Fixed versioning issue

* Add titles to ICS feed endpoints

* Added errors to v1

* Added rate-limit to API v1

* feat: added v1-v2 differences and v1 auth

* Trying to eliminate reasons for v1 not showing on publication

* Used the swagger openapi validator

* remove deprecated v1 endpoints

* Moved api docs into new folders without api-reference

* Renamed api to api-reference

* removed the versioning

* Got rid of anchor warnings

* Fixed naming

* Just as a test - using the same v2 openapi spec for v1 reference

* Removed 'externalDocs' from v1

* Removed securitySchemes

* Updated the diff between v1/v2

* Added v1 in front of /attendees to test

* Moved paths up and removed externalDocs

* Testing - Added content to the response

* Reduced paths to 1

* Testing: anything at this point

* Fixed validation

* Moved the other .mdx files to see if that's disrupting something

* Trying with a tab

* Empty tags array

* Added back servers field

* Removed all other schemas

* Removed v1 for now

* Added platform docs

* Language fixes

* Added v1 back

* add API V1 response for attendees

* remove unnecessary endpoint docs in API V1

* Removing platform and API for now

* Updated v2 openapi doc

---------

Co-authored-by: Syed Ali Shahbaz <alishahbaz7@gmail.com>
2024-10-03 15:26:01 +04:00
Benny Joo 2146c04444 fix: i18n for app router (#16909)
* fix: translations for app router

* fix build error
2024-10-03 00:32:33 +01:00
Calcom BotandReplexica 0b94473c7f feat: update translations (#16911)
Co-authored-by: Replexica <support@replexica.com>
2024-10-02 17:44:36 -04:00
2a1dc619ee feat: Multiple Private links per Event Type (#15896)
* feat: Change hashedLink field to array

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Implement core single-use links logic

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Get private link from list of hashedLinks on event list page

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix defalut single-use links form field value

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix some type errors while compiling

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Use onChange callback instead of setting form values directly

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Add e2e tests for single-use links

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Refactor single-use-links admin interface

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix settings toggle bugs

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* chore: Remove redundant inline comments

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Remove debug statements

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* chore: Remove single-use links e2e tests

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Remove private-link feature and override with single-use-links

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix type errors

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Remove redundant migrations

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Add managedEvents restriction

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix single-use-links for org

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix recommended UI changes

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix duration not respected for private links

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix team event page title

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Add logic to copy each single-use-links from event listing page

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Add single-use links support for managed event types

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix some type errors

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix type errors

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Disable adding new single-use links when field is locked

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Address feedbacks

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Hide add new link button for locked single-use link field

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* chore: Use empty string for single-use link fallback value condition

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix org single-use links in listing page

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Auto toggle unlock button for managed event's single-use links option

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* Revert "feat: Auto toggle unlock button for managed event's single-use links option"

This reverts commit 5a2ed6f0bf428d52de153335499f02f42ccdf18f.

* chore: Disable parent toggle for single-use-links

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* feat: Remove tooltip and give info message below field

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* add tooltip

* tooltip message

* fix: Fix typo

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix typescript type errors

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* fix: Fix few unit tests

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* refactor: Remove redundant query

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

* merge conflict fix

* More merge conflict fix and refactor

* fix tests, code refactor

* fix: type check

* fix: duration config and keep links when updating event type

* fix: e2e

* refactor: Replace single-use-links with multiple-private-links

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>

---------

Signed-off-by: Souptik Datta <souptikdatta2001@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Amit91848 <samit91848@gmail.com>
2024-10-03 00:58:54 +05:30
Benny JooandKeith Williams 48a2fc2f67 fix: translations for sidebar (#16910)
* fix: translations for sidebar

* Update apps/web/public/static/locales/en/common.json

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-10-02 18:21:25 +00:00
4553455098 chore: refactor shell to individual files (#16893)
* banners

* useAuthHooks

* fixes to redirect and banner

* extract useIntercom to custom hook

* use app theme

* extract user-dropdown to new component

* Navigation Item

* navigation and profile dropdown

* Fix import

* navigation and sidebar

* fix type errors

* fix banners being an async call

* fix types

* fix banner prop type

* fix mobile nav item import

* fix banner types

* (revert) layout banner render method to fix type error

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2024-10-02 15:35:56 +01:00
b4f1b5aebe refactor: handleNewBooking #4 (#15673)
* refactor: handleNewBooking #3

* refactor: create booking factor

* refactor: handleNewBooking

* refactor: seats and rescheduleUId

* chore: remove comment

* fix: type err

* chore: add missing statement

* chore: use less params and other improvements

* chore: name

* chore: improvement

* fix: type err

* Typo fix

* chore: fix type err

* refactor: more readable

* refactor: improve code

* fix: conflicts

---------

Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2024-10-02 10:26:25 -04:00
a99e285d76 fix: fix ui overflow on phone for calendar settings (#16661)
* fix: fix ui overflow on phone for calendar settings

* fix: overflow issue with long emails

* Update CalendarSwitch.tsx

---------

Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2024-10-02 12:24:25 +00:00
Lauris Skraucis bdea436f8b docs: v2 refresh tokens and slots endpoints swagger (#16788)
* docs: oauth refresh endpoint

* docs: slots reserve and delete

* docs: get slots

* swagger

* fix: reserving slot

* Revert "fix: reserving slot"

This reverts commit 8a3ce8464d5dbf67e58da6d3b1aeb51df97240cb.

* Update oauth-flow.controller.ts
2024-10-02 08:44:05 +00:00
Alex van Andel 182d0fa228 fix: Better defaulting to NEXT_PUBLIC_LOGGER_LEVEL=4 (#16900)
* fix: Better defaulting to NEXT_PUBLIC_LOGGER_LEVEL=4

* chore: Minor fixes to prettyLogTemplate (as it wasnt very pretty)
2024-10-01 17:38:02 +00:00
Alex van Andel 0d7f560c43 chore: improve instrumentation deps (#16899)
* Remove Sentry from direct import in instrumentation file

* chore: Exclude Sentry configs when not needed
2024-10-01 17:52:13 +01:00
565 changed files with 30512 additions and 3651 deletions
+1 -1
View File
@@ -168,13 +168,13 @@ NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE=
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN=0
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE=
STRIPE_TEAM_MONTHLY_PRICE_ID=
STRIPE_TEAM_PRODUCT_ID=
STRIPE_ORG_MONTHLY_PRICE_ID=
STRIPE_WEBHOOK_SECRET=
STRIPE_WEBHOOK_SECRET_APPS=
STRIPE_PRIVATE_KEY=
STRIPE_CLIENT_ID=
# Use for internal Public API Keys and optional
API_KEY_PREFIX=cal_
# ***********************************************************************************************************
+1 -1
View File
@@ -12,7 +12,7 @@
## Mandatory Tasks (DO NOT REMOVE)
- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [ ] I have added a Docs issue [here](https://github.com/calcom/docs/issues/new) if this PR makes changes that would require a [documentation change](https://docs.cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.
## How should this be tested?
+1
View File
@@ -11,6 +11,7 @@ export const schemaTeamBaseBodyParams = Team.omit({ id: true, createdAt: true })
smsLockState: true,
smsLockReviewedByAdmin: true,
bookingLimits: true,
includeManagedEventsInLimits: true,
});
const schemaTeamRequiredParams = z.object({
@@ -14,7 +14,7 @@ export class BookingsRepository_2024_08_13 {
});
}
async getByIdsWithAttendeesAndUser(ids: number[]) {
async getByIdsWithAttendeesAndUserAndEvent(ids: number[]) {
return this.dbRead.prisma.booking.findMany({
where: {
id: {
@@ -24,6 +24,7 @@ export class BookingsRepository_2024_08_13 {
include: {
attendees: true,
user: true,
eventType: true,
},
});
}
@@ -36,7 +37,7 @@ export class BookingsRepository_2024_08_13 {
});
}
async getByIdWithAttendeesAndUser(id: number) {
async getByIdWithAttendeesAndUserAndEvent(id: number) {
return this.dbRead.prisma.booking.findUnique({
where: {
id,
@@ -44,11 +45,12 @@ export class BookingsRepository_2024_08_13 {
include: {
attendees: true,
user: true,
eventType: true,
},
});
}
async getByUidWithAttendeesAndUser(uid: string) {
async getByUidWithAttendeesAndUserAndEvent(uid: string) {
return this.dbRead.prisma.booking.findUnique({
where: {
uid,
@@ -56,11 +58,12 @@ export class BookingsRepository_2024_08_13 {
include: {
attendees: true,
user: true,
eventType: true,
},
});
}
async getRecurringByUidWithAttendeesAndUser(uid: string) {
async getRecurringByUidWithAttendeesAndUserAndEvent(uid: string) {
return this.dbRead.prisma.booking.findMany({
where: {
recurringEventId: uid,
@@ -68,6 +71,7 @@ export class BookingsRepository_2024_08_13 {
include: {
attendees: true,
user: true,
eventType: true,
},
});
}
@@ -1,8 +1,6 @@
import { BookingUidGuard } from "@/ee/bookings/2024-08-13/guards/booking-uid.guard";
import { CancelBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/cancel-booking.output";
import { CreateBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/create-booking.output";
import { GetBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/get-booking.output";
import { GetBookingsOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/get-bookings.output";
import { MarkAbsentBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/mark-absent.output";
import { RescheduleBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/reschedule-booking.output";
import { BookingsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/bookings.service";
@@ -36,6 +34,7 @@ import { User } from "@prisma/client";
import { Request } from "express";
import { BOOKING_READ, BOOKING_WRITE, SUCCESS_STATUS } from "@calcom/platform-constants";
import { GetBookingOutput_2024_08_13, GetBookingsOutput_2024_08_13 } from "@calcom/platform-types";
import {
CreateBookingInputPipe,
CreateBookingInput,
@@ -1,7 +1,6 @@
import { bootstrap } from "@/app";
import { AppModule } from "@/app.module";
import { CreateBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/create-booking.output";
import { GetBookingsOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/get-bookings.output";
import { CreateScheduleInput_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/inputs/create-schedule.input";
import { SchedulesModule_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/schedules.module";
import { SchedulesService_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/services/schedules.service";
@@ -29,6 +28,7 @@ import {
CreateBookingInput_2024_08_13,
BookingOutput_2024_08_13,
RecurringBookingOutput_2024_08_13,
GetBookingsOutput_2024_08_13,
} from "@calcom/platform-types";
import { PlatformOAuthClient, Team } from "@calcom/prisma/client";
@@ -2,8 +2,6 @@ import { bootstrap } from "@/app";
import { AppModule } from "@/app.module";
import { CancelBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/cancel-booking.output";
import { CreateBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/create-booking.output";
import { GetBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/get-booking.output";
import { GetBookingsOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/get-bookings.output";
import { MarkAbsentBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/mark-absent.output";
import { RescheduleBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/reschedule-booking.output";
import { CreateScheduleInput_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/inputs/create-schedule.input";
@@ -30,6 +28,7 @@ import {
VERSION_2024_08_13,
X_CAL_CLIENT_ID,
} from "@calcom/platform-constants";
import { GetBookingOutput_2024_08_13, GetBookingsOutput_2024_08_13 } from "@calcom/platform-types";
import {
CreateBookingInput_2024_08_13,
BookingOutput_2024_08_13,
@@ -58,6 +57,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
let user: User;
let eventTypeId: number;
const eventTypeSlug = "peer-coding";
let recurringEventTypeId: number;
let createdBooking: BookingOutput_2024_08_13;
@@ -100,7 +100,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
};
await schedulesService.createUserSchedule(user.id, userSchedule);
const event = await eventTypesRepositoryFixture.create(
{ title: "peer coding", slug: "peer-coding", length: 60 },
{ title: "peer coding", slug: eventTypeSlug, length: 60 },
user.id
);
eventTypeId = event.id;
@@ -184,7 +184,10 @@ describe("Bookings Endpoints 2024-08-13", () => {
timeZone: "Europe/Rome",
language: "it",
},
meetingUrl: "https://meet.google.com/abc-def-ghi",
location: "https://meet.google.com/abc-def-ghi",
bookingFieldsResponses: {
customField: "customValue",
},
};
return request(app.getHttpServer())
@@ -208,14 +211,24 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.end).toEqual(new Date(Date.UTC(2030, 0, 8, 14, 0, 0)).toISOString());
expect(data.duration).toEqual(60);
expect(data.eventTypeId).toEqual(eventTypeId);
expect(data.eventType).toEqual({
id: eventTypeId,
slug: eventTypeSlug,
});
expect(data.attendees[0]).toEqual({
name: body.attendee.name,
timeZone: body.attendee.timeZone,
language: body.attendee.language,
absent: false,
});
expect(data.meetingUrl).toEqual(body.meetingUrl);
expect(data.location).toEqual(body.location);
expect(data.meetingUrl).toEqual(body.location);
expect(data.absentHost).toEqual(false);
expect(data.bookingFieldsResponses).toEqual({
name: body.attendee.name,
email: body.attendee.email,
...body.bookingFieldsResponses,
});
createdBooking = data;
} else {
throw new Error(
@@ -235,7 +248,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
timeZone: "Europe/Rome",
language: "it",
},
meetingUrl: "https://meet.google.com/abc-def-ghi",
location: "https://meet.google.com/abc-def-ghi",
};
return request(app.getHttpServer())
@@ -268,7 +281,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
language: body.attendee.language,
absent: false,
});
expect(firstBooking.meetingUrl).toEqual(body.meetingUrl);
expect(firstBooking.location).toEqual(body.location);
expect(firstBooking.recurringBookingUid).toBeDefined();
expect(firstBooking.absentHost).toEqual(false);
@@ -288,7 +301,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
language: body.attendee.language,
absent: false,
});
expect(secondBooking.meetingUrl).toEqual(body.meetingUrl);
expect(secondBooking.location).toEqual(body.location);
expect(secondBooking.absentHost).toEqual(false);
const thirdBooking = data[2];
@@ -307,7 +320,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
language: body.attendee.language,
absent: false,
});
expect(thirdBooking.meetingUrl).toEqual(body.meetingUrl);
expect(thirdBooking.location).toEqual(body.location);
expect(thirdBooking.absentHost).toEqual(false);
createdRecurringBooking = data;
@@ -343,7 +356,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.duration).toEqual(createdBooking.duration);
expect(data.eventTypeId).toEqual(createdBooking.eventTypeId);
expect(data.attendees[0]).toEqual(createdBooking.attendees[0]);
expect(data.meetingUrl).toEqual(createdBooking.meetingUrl);
expect(data.location).toEqual(createdBooking.location);
expect(data.absentHost).toEqual(createdBooking.absentHost);
} else {
throw new Error(
@@ -377,7 +390,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.eventTypeId).toEqual(createdRecurringBooking[0].eventTypeId);
expect(data.recurringBookingUid).toEqual(createdRecurringBooking[0].recurringBookingUid);
expect(data.attendees[0]).toEqual(createdRecurringBooking[0].attendees[0]);
expect(data.meetingUrl).toEqual(createdRecurringBooking[0].meetingUrl);
expect(data.location).toEqual(createdRecurringBooking[0].location);
expect(data.absentHost).toEqual(createdRecurringBooking[0].absentHost);
} else {
throw new Error(
@@ -414,7 +427,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(firstBooking.eventTypeId).toEqual(createdRecurringBooking[0].eventTypeId);
expect(firstBooking.recurringBookingUid).toEqual(recurringBookingUid);
expect(firstBooking.attendees[0]).toEqual(createdRecurringBooking[0].attendees[0]);
expect(firstBooking.meetingUrl).toEqual(createdRecurringBooking[0].meetingUrl);
expect(firstBooking.location).toEqual(createdRecurringBooking[0].location);
expect(firstBooking.absentHost).toEqual(createdRecurringBooking[0].absentHost);
const secondBooking = data[1];
@@ -428,7 +441,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(secondBooking.eventTypeId).toEqual(createdRecurringBooking[1].eventTypeId);
expect(secondBooking.recurringBookingUid).toEqual(recurringBookingUid);
expect(secondBooking.attendees[0]).toEqual(createdRecurringBooking[1].attendees[0]);
expect(secondBooking.meetingUrl).toEqual(createdRecurringBooking[1].meetingUrl);
expect(secondBooking.location).toEqual(createdRecurringBooking[1].location);
expect(secondBooking.absentHost).toEqual(createdRecurringBooking[1].absentHost);
const thirdBooking = data[2];
@@ -442,7 +455,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(thirdBooking.eventTypeId).toEqual(createdRecurringBooking[2].eventTypeId);
expect(thirdBooking.recurringBookingUid).toEqual(recurringBookingUid);
expect(thirdBooking.attendees[0]).toEqual(createdRecurringBooking[2].attendees[0]);
expect(thirdBooking.meetingUrl).toEqual(createdRecurringBooking[2].meetingUrl);
expect(thirdBooking.location).toEqual(createdRecurringBooking[2].location);
expect(thirdBooking.absentHost).toEqual(createdRecurringBooking[2].absentHost);
createdRecurringBooking = data;
@@ -764,7 +777,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.duration).toEqual(createdBooking.duration);
expect(data.eventTypeId).toEqual(createdBooking.eventTypeId);
expect(data.attendees[0]).toEqual(createdBooking.attendees[0]);
expect(data.meetingUrl).toEqual(createdBooking.meetingUrl);
expect(data.location).toEqual(createdBooking.location);
expect(data.absentHost).toEqual(createdBooking.absentHost);
rescheduledBooking = data;
@@ -815,7 +828,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.recurringBookingUid).toEqual(createdRecurringBooking[0].recurringBookingUid);
expect(data.eventTypeId).toEqual(createdRecurringBooking[0].eventTypeId);
expect(data.attendees[0]).toEqual(createdRecurringBooking[0].attendees[0]);
expect(data.meetingUrl).toEqual(createdRecurringBooking[0].meetingUrl);
expect(data.location).toEqual(createdRecurringBooking[0].location);
expect(data.absentHost).toEqual(createdRecurringBooking[0].absentHost);
const oldBooking = await bookingsRepositoryFixture.getByUid(createdRecurringBooking[0].uid);
@@ -885,7 +898,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.duration).toEqual(booking.duration);
expect(data.eventTypeId).toEqual(booking.eventTypeId);
expect(data.attendees[0]).toEqual(booking.attendees[0]);
expect(data.meetingUrl).toEqual(booking.meetingUrl);
expect(data.location).toEqual(booking.location);
});
});
@@ -918,7 +931,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.eventTypeId).toEqual(booking.eventTypeId);
expect(data.attendees[0].absent).toEqual(true);
expect(data.absentHost).toEqual(booking.absentHost);
expect(data.meetingUrl).toEqual(booking.meetingUrl);
expect(data.location).toEqual(booking.location);
});
});
});
@@ -955,7 +968,7 @@ describe("Bookings Endpoints 2024-08-13", () => {
expect(data.duration).toEqual(rescheduledBooking.duration);
expect(data.eventTypeId).toEqual(rescheduledBooking.eventTypeId);
expect(data.attendees[0]).toEqual(rescheduledBooking.attendees[0]);
expect(data.meetingUrl).toEqual(rescheduledBooking.meetingUrl);
expect(data.location).toEqual(rescheduledBooking.location);
expect(data.absentHost).toEqual(rescheduledBooking.absentHost);
const cancelledBooking = await bookingsRepositoryFixture.getByUid(rescheduledBooking.uid);
@@ -73,7 +73,9 @@ export class BookingsService_2024_08_13 {
const bookingRequest = await this.inputService.createBookingRequest(request, body);
const booking = await handleInstantMeeting(bookingRequest);
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUser(booking.bookingId);
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUserAndEvent(
booking.bookingId
);
if (!databaseBooking) {
throw new Error(`Booking with id=${booking.bookingId} was not found in the database`);
}
@@ -94,7 +96,7 @@ export class BookingsService_2024_08_13 {
throw new Error("Recurring booking was not created");
}
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUser(uid);
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUserAndEvent(uid);
return this.outputService.getOutputRecurringBookings(recurringBooking);
}
@@ -106,7 +108,7 @@ export class BookingsService_2024_08_13 {
throw new Error("Booking was not created");
}
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUser(booking.id);
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUserAndEvent(booking.id);
if (!databaseBooking) {
throw new Error(`Booking with id=${booking.id} was not found in the database`);
}
@@ -115,7 +117,7 @@ export class BookingsService_2024_08_13 {
}
async getBooking(uid: string) {
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUser(uid);
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUserAndEvent(uid);
if (booking) {
const isRecurring = !!booking.recurringEventId;
@@ -125,7 +127,7 @@ export class BookingsService_2024_08_13 {
return this.outputService.getOutputBooking(booking);
}
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUser(uid);
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUserAndEvent(uid);
if (!recurringBooking.length) {
throw new NotFoundException(`Booking with uid=${uid} was not found in the database`);
}
@@ -149,7 +151,7 @@ export class BookingsService_2024_08_13 {
// note(Lauris): fetchedBookings don't have attendees information and responses and i don't want to add them to the handler query,
// because its used elsewhere in code that does not need that information, so i get ids, fetch bookings and then return them formatted in same order as ids.
const ids = fetchedBookings.bookings.map((booking) => booking.id);
const bookings = await this.bookingsRepository.getByIdsWithAttendeesAndUser(ids);
const bookings = await this.bookingsRepository.getByIdsWithAttendeesAndUserAndEvent(ids);
const bookingMap = new Map(bookings.map((booking) => [booking.id, booking]));
const orderedBookings = ids.map((id) => bookingMap.get(id));
@@ -162,6 +164,7 @@ export class BookingsService_2024_08_13 {
const formatted = {
...booking,
eventType: booking.eventType,
eventTypeId: booking.eventTypeId,
startTime: new Date(booking.startTime),
endTime: new Date(booking.endTime),
@@ -191,7 +194,7 @@ export class BookingsService_2024_08_13 {
throw new Error("Booking was not created");
}
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUser(booking.id);
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUserAndEvent(booking.id);
if (!databaseBooking) {
throw new Error(`Booking with id=${booking.id} was not found in the database`);
}
@@ -226,7 +229,7 @@ export class BookingsService_2024_08_13 {
userId: bookingOwnerId,
});
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUser(bookingUid);
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUserAndEvent(bookingUid);
if (!booking) {
throw new Error(`Booking with uid=${bookingUid} was not found in the database`);
@@ -89,7 +89,7 @@ export class InputBookingsService_2024_08_13 {
? await this.createBookingRequestOAuthClientParams(oAuthClientId)
: DEFAULT_PLATFORM_PARAMS;
const location = request.body.meetingUrl;
const location = request.body.location || request.body.meetingUrl;
Object.assign(newRequest, { userId, ...oAuthParams, platformBookingLocation: location });
newRequest.body = { ...bodyTransformed, noEmail: !oAuthParams.arePlatformEmailsEnabled };
@@ -147,7 +147,7 @@ export class InputBookingsService_2024_08_13 {
? await this.createBookingRequestOAuthClientParams(oAuthClientId)
: DEFAULT_PLATFORM_PARAMS;
const location = request.body.meetingUrl;
const location = request.body.location || request.body.meetingUrl;
Object.assign(newRequest, {
userId,
...oAuthParams,
@@ -257,7 +257,7 @@ export class InputBookingsService_2024_08_13 {
}
async transformInputRescheduleBooking(bookingUid: string, inputBooking: RescheduleBookingInput_2024_08_13) {
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUser(bookingUid);
const booking = await this.bookingsRepository.getByUidWithAttendeesAndUserAndEvent(bookingUid);
if (!booking) {
throw new NotFoundException(`Booking with uid=${bookingUid} not found`);
}
@@ -390,7 +390,9 @@ export class InputBookingsService_2024_08_13 {
async transformInputCancelBooking(bookingUid: string, inputBooking: CancelBookingInput_2024_08_13) {
let allRemainingBookings = false;
let uid = bookingUid;
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUser(bookingUid);
const recurringBooking = await this.bookingsRepository.getRecurringByUidWithAttendeesAndUserAndEvent(
bookingUid
);
if (recurringBooking.length) {
// note(Lauirs): this means that bookingUid is equal to recurringEventId on individual bookings of recurring one aka main recurring event
@@ -7,14 +7,20 @@ import { z } from "zod";
import { BookingOutput_2024_08_13, RecurringBookingOutput_2024_08_13 } from "@calcom/platform-types";
import { Booking } from "@calcom/prisma/client";
export const bookingResponsesSchema = z.object({
email: z.string(),
name: z.string(),
guests: z.array(z.string()).optional(),
rescheduledReason: z.string().optional(),
});
export const bookingResponsesSchema = z
.object({
email: z.string(),
name: z.string(),
guests: z.array(z.string()).optional(),
rescheduledReason: z.string().optional(),
})
.passthrough();
type DatabaseBooking = Booking & {
eventType: {
id: number;
slug: string;
} | null;
attendees: {
name: string;
email: string;
@@ -38,6 +44,8 @@ export class OutputBookingsService_2024_08_13 {
const booking = {
id: databaseBooking.id,
uid: databaseBooking.uid,
title: databaseBooking.title,
description: databaseBooking.description,
hosts: [databaseBooking.user],
status: databaseBooking.status.toLowerCase(),
cancellationReason: databaseBooking.cancellationReason || undefined,
@@ -46,6 +54,8 @@ export class OutputBookingsService_2024_08_13 {
start: databaseBooking.startTime,
end: databaseBooking.endTime,
duration,
eventType: databaseBooking.eventType,
// note(Lauris): eventTypeId is deprecated
eventTypeId: databaseBooking.eventTypeId,
attendees: databaseBooking.attendees.map((attendee) => ({
name: attendee.name,
@@ -55,18 +65,22 @@ export class OutputBookingsService_2024_08_13 {
absent: !!attendee.noShow,
})),
guests: bookingResponses.guests,
location: databaseBooking.location,
// note(Lauris): meetingUrl is deprecated
meetingUrl: databaseBooking.location,
absentHost: !!databaseBooking.noShowHost,
};
return plainToClass(BookingOutput_2024_08_13, booking, { strategy: "excludeAll" });
const bookingTransformed = plainToClass(BookingOutput_2024_08_13, booking, { strategy: "excludeAll" });
bookingTransformed.bookingFieldsResponses = bookingResponses;
return bookingTransformed;
}
async getOutputRecurringBookings(databaseBookings: DatabaseBooking[]) {
const transformed = [];
for (const booking of databaseBookings) {
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUser(booking.id);
const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUserAndEvent(booking.id);
if (!databaseBooking) {
throw new Error(`Booking with id=${booking.id} was not found in the database`);
}
@@ -87,6 +101,8 @@ export class OutputBookingsService_2024_08_13 {
const booking = {
id: databaseBooking.id,
uid: databaseBooking.uid,
title: databaseBooking.title,
description: databaseBooking.description,
hosts: [databaseBooking.user],
status: databaseBooking.status.toLowerCase(),
cancellationReason: databaseBooking.cancellationReason || undefined,
@@ -95,6 +111,8 @@ export class OutputBookingsService_2024_08_13 {
start: databaseBooking.startTime,
end: databaseBooking.endTime,
duration,
eventType: databaseBooking.eventType,
// note(Lauris): eventTypeId is deprecated
eventTypeId: databaseBooking.eventTypeId,
attendees: databaseBooking.attendees.map((attendee) => ({
name: attendee.name,
@@ -104,9 +122,12 @@ export class OutputBookingsService_2024_08_13 {
absent: !!attendee.noShow,
})),
guests: bookingResponses.guests,
location: databaseBooking.location,
// note(Lauris): meetingUrl is deprecated
meetingUrl: databaseBooking.location,
recurringBookingUid: databaseBooking.recurringEventId,
absentHost: !!databaseBooking.noShowHost,
bookingFieldsResponses: databaseBooking.responses,
};
return plainToClass(RecurringBookingOutput_2024_08_13, booking, { strategy: "excludeAll" });
+3
View File
@@ -21,6 +21,9 @@ export type Environment = {
API_KEY_PREFIX: string;
DOCS_URL: string;
RATE_LIMIT_DEFAULT_TTL_MS: number;
RATE_LIMIT_DEFAULT_LIMIT_API_KEY: number;
RATE_LIMIT_DEFAULT_LIMIT_OAUTH_CLIENT: number;
RATE_LIMIT_DEFAULT_LIMIT_ACCESS_TOKEN: number;
RATE_LIMIT_DEFAULT_LIMIT: number;
RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS: number;
};
+52 -13
View File
@@ -22,18 +22,23 @@ const rateLimitSchema = z.object({
ttl: z.number(),
blockDuration: z.number(),
});
type RateLimitType = z.infer<typeof rateLimitSchema>;
const rateLimitsSchema = z.array(rateLimitSchema);
const sixtySecondsMs = 60 * 1000;
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
private logger = new Logger("CustomThrottlerGuard");
private defaultTttl = Number(getEnv("RATE_LIMIT_DEFAULT_TTL_MS", 60 * 1000));
private defaultTttl = Number(getEnv("RATE_LIMIT_DEFAULT_TTL_MS", sixtySecondsMs));
private defaultLimitApiKey = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_API_KEY", 120));
private defaultLimitOAuthClient = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_OAUTH_CLIENT", 500));
private defaultLimitAccessToken = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_ACCESS_TOKEN", 500));
private defaultLimit = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT", 120));
private defaultBlockDuration = Number(getEnv("RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS", 60 * 1000));
private defaultBlockDuration = Number(getEnv("RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS", sixtySecondsMs));
constructor(
options: ThrottlerModuleOptions,
@@ -51,6 +56,11 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
const request = context.switchToHttp().getRequest<Request>();
const response = context.switchToHttp().getResponse<Response>();
const tracker = await this.getTracker(request);
this.logger.log(
`Tracker "${tracker}" generated based on: Bearer token "${request.get(
"Authorization"
)}", OAuth client ID "${request.get(X_CAL_CLIENT_ID)}" and IP "${request.ip}"`
);
if (tracker.startsWith("api_key_")) {
return this.handleApiKeyRequest(tracker, response);
@@ -78,7 +88,10 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
}
private async handleNonApiKeyRequest(tracker: string, response: Response): Promise<boolean> {
const rateLimit = this.getDefaultRateLimit();
const rateLimit = this.getDefaultRateLimit(tracker);
this.logger.log(`Tracker "${tracker}" uses default rate limits because it is not tracking api key:
${JSON.stringify(rateLimit, null, 2)}
`);
const { isBlocked } = await this.incrementRateLimit(tracker, rateLimit, response);
if (isBlocked) {
@@ -88,17 +101,25 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
return true;
}
private getDefaultRateLimit() {
private getDefaultRateLimit(tracker: string) {
return {
name: "default",
limit: this.getDefaultLimit(),
limit: this.getDefaultLimit(tracker),
ttl: this.getDefaultTtl(),
blockDuration: this.getDefaultBlockDuration(),
};
}
getDefaultLimit() {
return this.defaultLimit;
getDefaultLimit(tracker: string) {
if (tracker.startsWith("api_key_")) {
return this.defaultLimitApiKey;
} else if (tracker.startsWith("oauth_client_")) {
return this.defaultLimitOAuthClient;
} else if (tracker.startsWith("access_token_")) {
return this.defaultLimitAccessToken;
} else {
return this.defaultLimit;
}
}
getDefaultTtl() {
@@ -114,6 +135,9 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
const cachedRateLimits = await this.storageService.redis.get(cacheKey);
if (cachedRateLimits) {
this.logger.log(`Tracker "${tracker}" rate limits retrieved from redis cache:
${cachedRateLimits}
`);
return rateLimitsSchema.parse(JSON.parse(cachedRateLimits));
}
@@ -133,11 +157,18 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
select: { name: true, limit: true, ttl: true, blockDuration: true },
});
if (!rateLimits || rateLimits.length === 0) {
rateLimits = [this.getDefaultRateLimit()];
if (rateLimits) {
this.logger.log(`Tracker "${tracker}" rate limits retrieved from database:
${JSON.stringify(rateLimits, null, 2)}`);
}
await this.storageService.redis.setex(cacheKey, 3600, JSON.stringify(rateLimits));
if (!rateLimits || rateLimits.length === 0) {
rateLimits = [this.getDefaultRateLimit(tracker)];
this.logger.log(`Tracker "${tracker}" rate limits not found in database. Using default rate limits:
${JSON.stringify(rateLimits, null, 2)}`);
}
await this.storageService.redis.set(cacheKey, JSON.stringify(rateLimits), "EX", 3600);
return rateLimits;
}
@@ -163,7 +194,15 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
);
response.setHeader(`X-RateLimit-Reset-${nameFirstUpper}`, timeToBlockExpire || timeToExpire);
this.logger.log(`Rate limit for ${tracker} incremented. Remaining: ${limit - totalHits}`);
this.logger.log(
`Tracker "${tracker}" rate limit "${name}" incremented. isBlocked ${isBlocked}, totalHits ${totalHits}, timeToExpire ${timeToExpire}, timeToBlockExpire ${timeToBlockExpire}`
);
this.logger.log(
`Tracker "${tracker}" rate limit "${name}" response headers:
X-RateLimit-Limit-${nameFirstUpper}: ${limit},
X-RateLimit-Remaining-${nameFirstUpper}: ${timeToBlockExpire ? 0 : Math.max(0, limit - totalHits)},
X-RateLimit-Reset-${nameFirstUpper}: ${timeToBlockExpire || timeToExpire}`
);
return { isBlocked };
}
@@ -25,9 +25,11 @@ import {
import {
ApiTags as DocsTags,
ApiExcludeController as DocsExcludeController,
ApiExcludeEndpoint as DocsExcludeEndpoint,
ApiOperation as DocsOperation,
ApiOkResponse as DocsOkResponse,
ApiBadRequestResponse as DocsBadRequestResponse,
ApiHeader as DocsHeader,
} from "@nestjs/swagger";
import { Response as ExpressResponse } from "express";
@@ -37,8 +39,7 @@ import { SUCCESS_STATUS, X_CAL_SECRET_KEY } from "@calcom/platform-constants";
path: "/v2/oauth/:clientId",
version: API_VERSIONS_VALUES,
})
@DocsExcludeController(getEnv("NODE_ENV") === "production")
@DocsTags("OAuth - development only")
@DocsTags("OAuth")
export class OAuthFlowController {
constructor(
private readonly oauthClientRepository: OAuthClientRepository,
@@ -62,6 +63,7 @@ export class OAuthFlowController {
description:
"Bad request if the OAuth client is not found, if the redirect URI is invalid, or if the user has already authorized the client.",
})
@DocsExcludeEndpoint(getEnv("NODE_ENV") === "production")
async authorize(
@Param("clientId") clientId: string,
@Body() body: OAuthAuthorizeInput,
@@ -108,6 +110,7 @@ export class OAuthFlowController {
description:
"Bad request if the authorization code is missing, invalid, or if the client ID and secret do not match.",
})
@DocsExcludeEndpoint(getEnv("NODE_ENV") === "production")
async exchange(
@Headers("Authorization") authorization: string,
@Param("clientId") clientId: string,
@@ -138,6 +141,12 @@ export class OAuthFlowController {
@Post("/refresh")
@HttpCode(HttpStatus.OK)
@UseGuards(ApiAuthGuard)
@DocsTags("Managed users")
@DocsHeader({
name: X_CAL_SECRET_KEY,
description: "OAuth client secret key.",
required: true,
})
async refreshAccessToken(
@Param("clientId") clientId: string,
@Headers(X_CAL_SECRET_KEY) secretKey: string,
@@ -1,6 +1,8 @@
import { ApiProperty as DocsProperty } from "@nestjs/swagger";
import { IsString } from "class-validator";
export class RefreshTokenInput {
@IsString()
@DocsProperty({ description: "Managed user's refresh token." })
refreshToken!: string;
}
@@ -76,4 +76,8 @@ export class UpdateOrgTeamDto {
@IsOptional()
@IsString()
readonly bookingLimits?: string;
@IsOptional()
@IsBoolean()
readonly includeManagedEventsInLimits?: boolean;
}
@@ -1,7 +1,7 @@
import { API_VERSIONS_VALUES } from "@/lib/api-versions";
import { SlotsService } from "@/modules/slots/services/slots.service";
import { Query, Body, Controller, Get, Delete, Post, Req, Res } from "@nestjs/common";
import { ApiOperation, ApiTags as DocsTags } from "@nestjs/swagger";
import { ApiTags as DocsTags, ApiCreatedResponse, ApiOkResponse, ApiOperation } from "@nestjs/swagger";
import { Response as ExpressResponse, Request as ExpressRequest } from "express";
import { SUCCESS_STATUS } from "@calcom/platform-constants";
@@ -19,6 +19,21 @@ export class SlotsController {
constructor(private readonly slotsService: SlotsService) {}
@Post("/reserve")
@ApiCreatedResponse({
description: "Successful response returning uid of reserved slot.",
schema: {
type: "object",
properties: {
status: { type: "string", example: "success" },
data: {
type: "object",
properties: {
uid: { type: "string", example: "e2a7bcf9-cc7b-40a0-80d3-657d391775a6" },
},
},
},
},
})
@ApiOperation({ summary: "Reserve a slot" })
async reserveSlot(
@Body() body: ReserveSlotInput,
@@ -35,6 +50,15 @@ export class SlotsController {
}
@Delete("/selected-slot")
@ApiOkResponse({
description: "Response deleting reserved slot by uid.",
schema: {
type: "object",
properties: {
status: { type: "string", example: "success" },
},
},
})
@ApiOperation({ summary: "Delete a selected slot" })
async deleteSelectedSlot(
@Query() params: RemoveSelectedSlotInput,
@@ -50,6 +74,45 @@ export class SlotsController {
}
@Get("/available")
@ApiOkResponse({
description: "Available time slots retrieved successfully",
schema: {
type: "object",
properties: {
status: { type: "string", example: "success" },
data: {
type: "object",
properties: {
slots: {
type: "object",
additionalProperties: {
type: "array",
items: {
type: "object",
properties: {
time: { type: "string", format: "date-time", example: "2024-09-25T08:00:00.000Z" },
},
},
},
},
},
},
},
example: {
status: "success",
data: {
slots: {
"2024-09-25": [{ time: "2024-09-25T08:00:00.000Z" }, { time: "2024-09-25T08:15:00.000Z" }],
"2024-09-26": [
{ time: "2024-09-26T08:00:00.000Z" },
{ time: "2024-09-26T08:15:00.000Z" },
{ time: "2024-09-26T08:30:00.000Z" },
],
},
},
},
},
})
@ApiOperation({ summary: "Get available slots" })
async getAvailableSlots(
@Query() query: GetAvailableSlotsInput,
@@ -22,7 +22,7 @@ import {
BadRequestException,
Headers,
} from "@nestjs/common";
import { ApiTags as DocsTags } from "@nestjs/swagger";
import { ApiTags as DocsTags, ApiOperation } from "@nestjs/swagger";
import { plainToClass } from "class-transformer";
import { Request } from "express";
import { stringify } from "querystring";
@@ -40,6 +40,7 @@ export class StripeController {
@Get("/connect")
@UseGuards(ApiAuthGuard)
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: "Get stripe connect URL" })
async redirect(
@Req() req: Request,
@Headers("Authorization") authorization: string,
@@ -72,6 +73,7 @@ export class StripeController {
@Get("/save")
@UseGuards()
@Redirect(undefined, 301)
@ApiOperation({ summary: "Save stripe credentials" })
async save(
@Query("state") state: string,
@Query("code") code: string,
@@ -95,6 +97,7 @@ export class StripeController {
@Get("/check")
@UseGuards(ApiAuthGuard)
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: "Check stripe connection" })
async check(@GetUser() user: UserWithProfile): Promise<StripCredentialsCheckOutputResponseDto> {
return await this.stripeService.checkIfStripeAccountConnected(user.id);
}
+570 -157
View File
@@ -4108,6 +4108,147 @@
]
}
},
"/v2/oauth/{clientId}/authorize": {
"post": {
"operationId": "OAuthFlowController_authorize",
"summary": "Authorize an OAuth client",
"description": "Redirects the user to the specified 'redirect_uri' with an authorization code in query parameter if the client is authorized successfully. The code is then exchanged for access and refresh tokens via the `/exchange` endpoint.",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthAuthorizeInput"
}
}
}
},
"responses": {
"200": {
"description": "The user is redirected to the 'redirect_uri' with an authorization code in query parameter e.g. `redirectUri?code=secretcode.`"
},
"400": {
"description": "Bad request if the OAuth client is not found, if the redirect URI is invalid, or if the user has already authorized the client."
}
},
"tags": [
"OAuth"
]
}
},
"/v2/oauth/{clientId}/exchange": {
"post": {
"operationId": "OAuthFlowController_exchange",
"summary": "Exchange authorization code for access tokens",
"description": "Exchanges the authorization code received from the `/authorize` endpoint for access and refresh tokens. The authorization code should be provided in the 'Authorization' header prefixed with 'Bearer '.",
"parameters": [
{
"name": "Authorization",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
},
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExchangeAuthorizationCodeInput"
}
}
}
},
"responses": {
"200": {
"description": "Successfully exchanged authorization code for access and refresh tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KeysResponseDto"
}
}
}
},
"400": {
"description": "Bad request if the authorization code is missing, invalid, or if the client ID and secret do not match."
}
},
"tags": [
"OAuth"
]
}
},
"/v2/oauth/{clientId}/refresh": {
"post": {
"operationId": "OAuthFlowController_refreshAccessToken",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "x-cal-secret-key",
"required": true,
"in": "header",
"description": "OAuth client secret key.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefreshTokenInput"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KeysResponseDto"
}
}
}
}
},
"tags": [
"OAuth",
"Managed users"
]
}
},
"/v2/oauth-clients": {
"post": {
"operationId": "OAuthClientsController_createOAuthClient",
@@ -4306,145 +4447,6 @@
]
}
},
"/v2/oauth/{clientId}/authorize": {
"post": {
"operationId": "OAuthFlowController_authorize",
"summary": "Authorize an OAuth client",
"description": "Redirects the user to the specified 'redirect_uri' with an authorization code in query parameter if the client is authorized successfully. The code is then exchanged for access and refresh tokens via the `/exchange` endpoint.",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthAuthorizeInput"
}
}
}
},
"responses": {
"200": {
"description": "The user is redirected to the 'redirect_uri' with an authorization code in query parameter e.g. `redirectUri?code=secretcode.`"
},
"400": {
"description": "Bad request if the OAuth client is not found, if the redirect URI is invalid, or if the user has already authorized the client."
}
},
"tags": [
"OAuth - development only"
]
}
},
"/v2/oauth/{clientId}/exchange": {
"post": {
"operationId": "OAuthFlowController_exchange",
"summary": "Exchange authorization code for access tokens",
"description": "Exchanges the authorization code received from the `/authorize` endpoint for access and refresh tokens. The authorization code should be provided in the 'Authorization' header prefixed with 'Bearer '.",
"parameters": [
{
"name": "Authorization",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
},
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExchangeAuthorizationCodeInput"
}
}
}
},
"responses": {
"200": {
"description": "Successfully exchanged authorization code for access and refresh tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KeysResponseDto"
}
}
}
},
"400": {
"description": "Bad request if the authorization code is missing, invalid, or if the client ID and secret do not match."
}
},
"tags": [
"OAuth - development only"
]
}
},
"/v2/oauth/{clientId}/refresh": {
"post": {
"operationId": "OAuthFlowController_refreshAccessToken",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "x-cal-secret-key",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefreshTokenInput"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KeysResponseDto"
}
}
}
}
},
"tags": [
"OAuth - development only"
]
}
},
"/v2/schedules": {
"post": {
"operationId": "SchedulesController_2024_06_11_createSchedule",
@@ -4826,11 +4828,26 @@
},
"responses": {
"201": {
"description": "",
"description": "Successful response returning uid of reserved slot.",
"content": {
"application/json": {
"schema": {
"type": "object"
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success"
},
"data": {
"type": "object",
"properties": {
"uid": {
"type": "string",
"example": "e2a7bcf9-cc7b-40a0-80d3-657d391775a6"
}
}
}
}
}
}
}
@@ -4845,14 +4862,31 @@
"delete": {
"operationId": "SlotsController_deleteSelectedSlot",
"summary": "Delete a selected slot",
"parameters": [],
"parameters": [
{
"name": "uid",
"required": true,
"in": "query",
"description": "Unique identifier for the slot to be removed.",
"example": "e2a7bcf9-cc7b-40a0-80d3-657d391775a6",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"description": "Response deleting reserved slot by uid.",
"content": {
"application/json": {
"schema": {
"type": "object"
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success"
}
}
}
}
}
@@ -4867,14 +4901,128 @@
"get": {
"operationId": "SlotsController_getAvailableSlots",
"summary": "Get available slots",
"parameters": [],
"parameters": [
{
"name": "startTime",
"required": true,
"in": "query",
"description": "Start date string starting from which to fetch slots in UTC timezone.",
"example": "2022-06-14T00:00:00.000Z",
"schema": {
"type": "string"
}
},
{
"name": "endTime",
"required": true,
"in": "query",
"description": "End date string until which to fetch slots in UTC timezone.",
"example": "2022-06-14T23:59:59.999Z",
"schema": {
"type": "string"
}
},
{
"name": "eventTypeId",
"required": true,
"in": "query",
"description": "Event Type ID for which slots are being fetched.",
"example": 100,
"schema": {
"type": "number"
}
},
{
"name": "eventTypeSlug",
"required": true,
"in": "query",
"description": "Slug of the event type for which slots are being fetched.",
"schema": {
"type": "string"
}
},
{
"name": "usernameList",
"required": true,
"in": "query",
"description": "Only for dynamic events - list of usernames for which slots are being fetched.",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"name": "duration",
"required": true,
"in": "query",
"description": "Only for dynamic events - length of returned slots.",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "",
"description": "Available time slots retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object"
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success"
},
"data": {
"type": "object",
"properties": {
"slots": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object",
"properties": {
"time": {
"type": "string",
"format": "date-time",
"example": "2024-09-25T08:00:00.000Z"
}
}
}
}
}
}
}
},
"example": {
"status": "success",
"data": {
"slots": {
"2024-09-25": [
{
"time": "2024-09-25T08:00:00.000Z"
},
{
"time": "2024-09-25T08:15:00.000Z"
}
],
"2024-09-26": [
{
"time": "2024-09-26T08:00:00.000Z"
},
{
"time": "2024-09-26T08:15:00.000Z"
},
{
"time": "2024-09-26T08:30:00.000Z"
}
]
}
}
}
}
}
}
@@ -4885,6 +5033,98 @@
]
}
},
"/v2/stripe/connect": {
"get": {
"operationId": "StripeController_redirect",
"summary": "Get stripe connect URL",
"parameters": [
{
"name": "Authorization",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StripConnectOutputResponseDto"
}
}
}
}
},
"tags": [
"Stripe"
]
}
},
"/v2/stripe/save": {
"get": {
"operationId": "StripeController_save",
"summary": "Save stripe credentials",
"parameters": [
{
"name": "state",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "code",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StripCredentialsSaveOutputResponseDto"
}
}
}
}
},
"tags": [
"Stripe"
]
}
},
"/v2/stripe/check": {
"get": {
"operationId": "StripeController_check",
"summary": "Check stripe connection",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StripCredentialsCheckOutputResponseDto"
}
}
}
}
},
"tags": [
"Stripe"
]
}
},
"/v2/timezones": {
"get": {
"operationId": "TimezonesController_getTimeZones",
@@ -5693,7 +5933,8 @@
"type": "object",
"properties": {
"refreshToken": {
"type": "string"
"type": "string",
"description": "Managed user's refresh token."
}
},
"required": [
@@ -11097,6 +11338,60 @@
}
}
},
"StripConnectOutputDto": {
"type": "object",
"properties": {
"authUrl": {
"type": "string"
}
},
"required": [
"authUrl"
]
},
"StripConnectOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/StripConnectOutputDto"
}
},
"required": [
"status",
"data"
]
},
"StripCredentialsSaveOutputResponseDto": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
},
"required": [
"url"
]
},
"StripCredentialsCheckOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success"
}
},
"required": [
"status"
]
},
"GetDefaultScheduleOutput_2024_06_11": {
"type": "object",
"properties": {
@@ -11907,12 +12202,18 @@
},
"meetingUrl": {
"type": "string",
"description": "Meeting URL just for this booking. Displayed in email and calendar event. If not provided then cal video link will be generated.",
"description": "Deprecated - use 'location' instead. Meeting URL just for this booking. Displayed in email and calendar event. If not provided then cal video link will be generated.",
"example": "https://example.com/meeting",
"deprecated": true
},
"location": {
"type": "string",
"description": "Location for this booking. Displayed in email and calendar event.",
"example": "https://example.com/meeting"
},
"bookingFieldsResponses": {
"type": "object",
"description": "Booking field responses.",
"description": "Booking field responses consisting of an object with booking field slug as keys and user response as values.",
"example": {
"customField": "customValue"
}
@@ -11958,12 +12259,18 @@
},
"meetingUrl": {
"type": "string",
"description": "Meeting URL just for this booking. Displayed in email and calendar event. If not provided then cal video link will be generated.",
"description": "Deprecated - use 'location' instead. Meeting URL just for this booking. Displayed in email and calendar event. If not provided then cal video link will be generated.",
"example": "https://example.com/meeting",
"deprecated": true
},
"location": {
"type": "string",
"description": "Location for this booking. Displayed in email and calendar event.",
"example": "https://example.com/meeting"
},
"bookingFieldsResponses": {
"type": "object",
"description": "Booking field responses.",
"description": "Booking field responses consisting of an object with booking field slug as keys and user response as values.",
"example": {
"customField": "customValue"
}
@@ -12013,9 +12320,9 @@
"type": "string"
}
},
"meetingUrl": {
"location": {
"type": "string",
"description": "Meeting URL just for this booking. Displayed in email and calendar event. If not provided then cal video link will be generated.",
"description": "Location for this booking. Displayed in email and calendar event.",
"example": "https://example.com/meeting"
},
"bookingFieldsResponses": {
@@ -12032,6 +12339,23 @@
"attendee"
]
},
"EventType": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1
},
"slug": {
"type": "string",
"example": "some-event"
}
},
"required": [
"id",
"slug"
]
},
"BookingOutput_2024_08_13": {
"type": "object",
"properties": {
@@ -12043,6 +12367,14 @@
"type": "string",
"example": "booking_uid_123"
},
"title": {
"type": "string",
"example": "Consultation"
},
"description": {
"type": "string",
"example": "Learn how to integrate scheduling into marketplace."
},
"hosts": {
"type": "array",
"items": {
@@ -12086,7 +12418,12 @@
},
"eventTypeId": {
"type": "number",
"example": 45
"example": 50,
"deprecated": true,
"description": "Deprecated - rely on 'eventType' object containing the id instead."
},
"eventType": {
"$ref": "#/components/schemas/EventType"
},
"attendees": {
"type": "array",
@@ -12105,23 +12442,39 @@
}
},
"meetingUrl": {
"type": "string",
"description": "Deprecated - rely on 'location' field instead.",
"example": "https://example.com/recurring-meeting",
"deprecated": true
},
"location": {
"type": "string",
"example": "https://example.com/meeting"
},
"absentHost": {
"type": "boolean",
"example": true
},
"bookingFieldsResponses": {
"type": "object",
"description": "Booking field responses consisting of an object with booking field slug as keys and user response as values.",
"example": {
"customField": "customValue"
}
}
},
"required": [
"id",
"uid",
"title",
"description",
"hosts",
"status",
"start",
"end",
"duration",
"eventTypeId",
"eventType",
"attendees",
"absentHost"
]
@@ -12137,6 +12490,14 @@
"type": "string",
"example": "recurring_uid_123"
},
"title": {
"type": "string",
"example": "Recurring meeting"
},
"description": {
"type": "string",
"example": "Learn how to integrate scheduling into marketplace."
},
"hosts": {
"type": "array",
"items": {
@@ -12179,7 +12540,12 @@
},
"eventTypeId": {
"type": "number",
"example": 50
"example": 50,
"deprecated": true,
"description": "Deprecated - rely on 'eventType' object containing the id instead."
},
"eventType": {
"$ref": "#/components/schemas/EventType"
},
"recurringBookingUid": {
"type": "string",
@@ -12202,23 +12568,39 @@
}
},
"meetingUrl": {
"type": "string",
"description": "Deprecated - rely on 'location' field instead.",
"example": "https://example.com/recurring-meeting",
"deprecated": true
},
"location": {
"type": "string",
"example": "https://example.com/recurring-meeting"
},
"absentHost": {
"type": "boolean",
"example": false
},
"bookingFieldsResponses": {
"type": "object",
"description": "Booking field responses consisting of an object with booking field slug as keys and user response as values.",
"example": {
"customField": "customValue"
}
}
},
"required": [
"id",
"uid",
"title",
"description",
"hosts",
"status",
"start",
"end",
"duration",
"eventTypeId",
"eventType",
"recurringBookingUid",
"attendees",
"absentHost"
@@ -12282,6 +12664,9 @@
}
],
"description": "Booking data, which can be either a BookingOutput object, a RecurringBookingOutput object, or an array of RecurringBookingOutput objects"
},
"error": {
"type": "object"
}
},
"required": [
@@ -12313,6 +12698,9 @@
]
},
"description": "Array of booking data, which can contain either BookingOutput objects or RecurringBookingOutput objects"
},
"error": {
"type": "object"
}
},
"required": [
@@ -12468,7 +12856,32 @@
},
"ReserveSlotInput": {
"type": "object",
"properties": {}
"properties": {
"eventTypeId": {
"type": "number",
"description": "Event Type ID for which timeslot is being reserved.",
"example": 100
},
"slotUtcStartDate": {
"type": "string",
"description": "Start date of the slot in UTC timezone.",
"example": "2022-06-14T00:00:00.000Z"
},
"slotUtcEndDate": {
"type": "string",
"description": "End date of the slot in UTC timezone.",
"example": "2022-06-14T00:30:00.000Z"
},
"bookingUid": {
"type": "string",
"description": "Optional but only for events with seats. Used to retrieve booking of a seated event."
}
},
"required": [
"eventTypeId",
"slotUtcStartDate",
"slotUtcEndDate"
]
},
"UserWebhookOutputDto": {
"type": "object",
@@ -1,5 +1,5 @@
import { withAppDirSsr } from "app/WithAppDirSsr";
import type { PageProps } from "app/_types";
import { PageProps } from "app/_types";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsResult } from "next";
@@ -27,12 +27,12 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const legacyContext = buildLegacyCtx(headers(), cookies(), params, searchParams);
const data = await getData(legacyContext);
const form = "form" in data ? (data.form as { name?: string; description?: string }) : null;
const formName = form?.name ?? "Routing Forms";
const formDescription = form?.description ?? "";
const formName = form?.name;
const formDescription = form?.description;
return await _generateMetadata(
() => formName,
() => formDescription
(t) => formName ?? t("routing_forms"),
(t) => formDescription ?? t("routing_forms_description")
);
};
@@ -11,8 +11,8 @@ import CategoryPage, { type PageProps } from "~/apps/categories/[category]/categ
export const generateMetadata = async () => {
return await _generateMetadata(
() => "Apps Store",
() => "Connecting people, technology and the workplace."
(t) => t("app_store"),
(t) => t("app_store_description")
);
};
+2 -2
View File
@@ -8,8 +8,8 @@ import Page from "~/apps/categories/categories-view";
export const generateMetadata = async () => {
return await _generateMetadata(
() => "Apps Store",
() => "Connecting people, technology and the workplace."
(t) => t("app_store"),
(t) => t("app_store_description")
);
};
@@ -12,8 +12,8 @@ const getData = withAppDirSsg<Y>(getStaticProps);
export const generateMetadata = async () =>
await _generateMetadata(
() => "Bookings",
() => "Create events to share for people to book on your calendar."
(t) => t("bookings"),
(t) => t("bookings_description")
);
export const generateStaticParams = async () => {
+1 -1
View File
@@ -9,7 +9,7 @@ import InsightsPage from "~/insights/insights-view";
export const generateMetadata = async () =>
await _generateMetadata(
() => "Insights",
(t) => t("insights"),
(t) => t("insights_subtitle")
);
@@ -5,8 +5,8 @@ import PlatformView from "~/settings/platform/platform-view";
export const generateMetadata = async () => {
return await _generateMetadata(
() => "Platform",
() => "Manage everything related to platform."
(t) => t("platform"),
(t) => t("platform_description")
);
};
+1
View File
@@ -67,6 +67,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
lang={locale}
dir={direction}
style={embedColorScheme ? { colorScheme: embedColorScheme as string } : undefined}
suppressHydrationWarning
data-nextjs-router="app">
<head nonce={nonce}>
{!!process.env.NEXT_PUBLIC_HEAD_SCRIPTS && (
+1 -1
View File
@@ -42,7 +42,7 @@ export default function EnterprisePage() {
];
return (
<div>
<ShellMain heading="Enterprise" subtitle={t("enterprise_description")}>
<ShellMain heading={t("enterprise")} subtitle={t("enterprise_description")}>
<UpgradeTip
plan="enterprise"
title={t("create_your_org")}
+5 -11
View File
@@ -1,15 +1,9 @@
import * as Sentry from "@sentry/nextjs";
export function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
});
export async function register() {
if (process.env.NEXT_PUBLIC_SENTRY_DSN && process.env.NEXT_RUNTIME === "nodejs") {
await import("./sentry.server.config");
}
if (process.env.NEXT_RUNTIME === "edge") {
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
});
if (process.env.NEXT_PUBLIC_SENTRY_DSN && process.env.NEXT_RUNTIME === "edge") {
await import("./sentry.edge.config");
}
}
+7 -5
View File
@@ -71,10 +71,12 @@ const CustomI18nextProvider = (props: { children: React.ReactElement; i18n?: SSR
**/
const session = useSession();
const locale =
session?.data?.user.locale ?? typeof window !== "undefined"
? window.document.documentElement.lang || "en"
const fallbackLocale =
typeof window !== "undefined" && window.document.documentElement.lang
? window.document.documentElement.lang
: "en";
const newLocale = typeof window !== "undefined" && window.calNewLocale ? window.calNewLocale : null;
const locale = session?.data?.user.locale ?? newLocale ?? fallbackLocale;
useEffect(() => {
try {
@@ -139,10 +141,10 @@ const CalcomThemeProvider = (props: CalcomThemeProps) => {
const embedNamespace = searchParams ? getEmbedNamespace(searchParams) : null;
const isEmbedMode = typeof embedNamespace === "string";
const themeProviderProps = getThemeProviderProps({ props, isEmbedMode, embedNamespace });
const { key, ...themeProviderProps } = getThemeProviderProps({ props, isEmbedMode, embedNamespace });
return (
<ThemeProvider {...themeProviderProps}>
<ThemeProvider key={key} {...themeProviderProps}>
{/* Embed Mode can be detected reliably only on client side here as there can be static generated pages as well which can't determine if it's embed mode at backend */}
{/* color-scheme makes background:transparent not work in iframe which is required by embed. */}
{typeof window !== "undefined" && !isEmbedMode && (
+2 -2
View File
@@ -145,10 +145,10 @@ const CalcomThemeProvider = (props: CalcomThemeProps) => {
const embedNamespace = getEmbedNamespace(props.router.query);
const isEmbedMode = typeof embedNamespace === "string";
const themeProviderProps = getThemeProviderProps({ props, isEmbedMode, embedNamespace });
const { key, ...themeProviderProps } = getThemeProviderProps({ props, isEmbedMode, embedNamespace });
return (
<ThemeProvider {...themeProviderProps}>
<ThemeProvider key={key} {...themeProviderProps}>
{/* Embed Mode can be detected reliably only on client side here as there can be static generated pages as well which can't determine if it's embed mode at backend */}
{/* color-scheme makes background:transparent not work in iframe which is required by embed. */}
{typeof window !== "undefined" && !isEmbedMode && (
@@ -127,6 +127,7 @@ async function getUserPageProps(context: GetServerSidePropsContext) {
queryDuration,
eventData.length
),
durationConfig: eventData.metadata?.multipleDuration ?? [],
booking,
user: name,
slug,
+4 -2
View File
@@ -98,10 +98,12 @@ export default function Apps({ categories, appStore, userAdminTeams }: PageProps
}
export const LayoutWrapper = (page: React.ReactElement) => {
const { t } = useLocale();
return (
<Shell
title="Apps Store"
description="Create forms to direct attendees to the correct destinations."
title={t("app_store")}
description={t("app_store_description")}
withoutMain={true}
hideHeadingOnMobile>
{page}
@@ -21,8 +21,8 @@ export default function Apps({ apps }: PageProps) {
<Shell
isPublic
backPath="/apps"
title="Apps Store"
description="Connecting people, technology and the workplace."
title={t("app_store")}
description={t("app_store_description")}
smallHeading
heading={
<>
@@ -15,12 +15,7 @@ export default function Apps({ categories }: PageProps) {
const { t, isLocaleReady } = useLocale();
return (
<Shell
isPublic
large
hideHeadingOnMobile
title="Apps Store"
description="Connecting people, technology and the workplace.">
<Shell isPublic large hideHeadingOnMobile title={t("app_store")} description={t("app_store_description")}>
<div className="text-md flex items-center gap-1 px-4 pb-3 pt-3 font-normal md:px-8 lg:px-0 lg:pt-0">
<Link
href="/apps"
@@ -213,11 +213,11 @@ export default function AvailabilityPage({ currentOrg }: PageProps) {
<div>
<Shell
heading={t("availability")}
title="Availability"
description="Configure times when you are available for bookings."
subtitle={t("configure_availability")}
title={t("availability")}
description={t("configure_availability")}
hideHeadingOnMobile
withoutMain={false}
subtitle={t("configure_availability")}
CTA={
<div className="flex gap-2">
<ToggleGroup
@@ -151,8 +151,8 @@ export default function Bookings() {
hideHeadingOnMobile
heading={t("bookings")}
subtitle={t("bookings_description")}
title="Bookings"
description="Create events to share for people to book on your calendar.">
title={t("bookings")}
description={t("bookings_description")}>
<div className="flex flex-col">
<div className="flex flex-row flex-wrap justify-between">
<HorizontalTabs tabs={tabs} />
@@ -161,7 +161,11 @@ export default function Success(props: PageProps) {
const [calculatedDuration, setCalculatedDuration] = useState<number | undefined>(undefined);
const [comment, setComment] = useState("");
const parsedRating = rating ? parseInt(rating, 10) : 3;
const currentUserEmail = searchParams?.get("cancelledBy") ?? session?.user?.email ?? undefined;
const currentUserEmail =
searchParams?.get("rescheduledBy") ??
searchParams?.get("cancelledBy") ??
session?.user?.email ??
undefined;
const defaultRating = isNaN(parsedRating) ? 3 : parsedRating > 5 ? 5 : parsedRating < 1 ? 1 : parsedRating;
const [rateValue, setRateValue] = useState<number>(defaultRating);
@@ -16,6 +16,7 @@ export default function Type({
entity,
duration,
hashedLink,
durationConfig,
}: PageProps) {
return (
<main className={getBookerWrapperClasses({ isEmbed: !!isEmbed })}>
@@ -35,6 +36,7 @@ export default function Type({
entity={entity}
duration={duration}
hashedLink={hashedLink}
durationConfig={durationConfig}
/>
</main>
);
@@ -19,7 +19,6 @@ import { getTeamsFiltersFromQuery } from "@calcom/features/filters/lib/getTeamsF
import Shell from "@calcom/features/shell/Shell";
import { parseEventTypeColor } from "@calcom/lib";
import { APP_NAME } from "@calcom/lib/constants";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
@@ -250,6 +249,7 @@ export const InfiniteEventTypeList = ({
const [deleteDialogTypeSchedulingType, setDeleteDialogSchedulingType] = useState<SchedulingType | null>(
null
);
const [privateLinkCopyIndices, setPrivateLinkCopyIndices] = useState<Record<string, number>>({});
const utils = trpc.useUtils();
const mutation = trpc.viewer.eventTypeOrder.useMutation({
@@ -443,8 +443,11 @@ export const InfiniteEventTypeList = ({
return page?.eventTypes?.map((type, index) => {
const embedLink = `${group.profile.slug}/${type.slug}`;
const calLink = `${bookerUrl}/${embedLink}`;
const isPrivateURLEnabled = type.hashedLink?.link;
const placeholderHashedLink = `${WEBSITE_URL}/d/${type.hashedLink?.link}/${type.slug}`;
const isPrivateURLEnabled =
type.hashedLink && type.hashedLink.length > 0
? type.hashedLink[privateLinkCopyIndices[type.slug] ?? 0]?.link
: "";
const placeholderHashedLink = `${bookerUrl}/d/${isPrivateURLEnabled}/${type.slug}`;
const isManagedEventType = type.schedulingType === SchedulingType.MANAGED;
const isChildrenManagedEventType =
type.metadata?.managedEventConfig !== undefined &&
@@ -544,6 +547,11 @@ export const InfiniteEventTypeList = ({
onClick={() => {
showToast(t("private_link_copied"), "success");
navigator.clipboard.writeText(placeholderHashedLink);
setPrivateLinkCopyIndices((prev) => {
const prevIndex = prev[type.slug] ?? 0;
prev[type.slug] = (prevIndex + 1) % type.hashedLink.length;
return prev;
});
}}
/>
</Tooltip>
+3 -3
View File
@@ -53,10 +53,10 @@ export default function InsightsPage() {
<div>
<Shell
withoutMain={false}
heading="Insights"
heading={t("insights")}
subtitle={t("insights_subtitle")}
title="Insights"
description="View booking insights across your events.">
title={t("insights")}
description={t("insights_subtitle")}>
<UpgradeTip
plan="team"
title={t("make_informed_decisions")}
+2 -1
View File
@@ -1,6 +1,7 @@
"use client";
import Shell, { MobileNavigationMoreItems } from "@calcom/features/shell/Shell";
import Shell from "@calcom/features/shell/Shell";
import { MobileNavigationMoreItems } from "@calcom/features/shell/navigation/Navigation";
import { useLocale } from "@calcom/lib/hooks/useLocale";
export default function MorePage() {
@@ -192,15 +192,21 @@ const AppearanceView = ({
</div>
<Form
form={userAppThemeFormMethods}
handleSubmit={(values) => {
handleSubmit={({ appTheme }) => {
if (appTheme === "light" || appTheme === "dark") {
mutation.mutate({
appTheme,
});
return;
}
mutation.mutate({
appTheme: values.appTheme === "" ? null : values.appTheme,
appTheme: null,
});
}}>
<div className="border-subtle flex flex-col justify-between border-x px-6 py-8 sm:flex-row">
<ThemeLabel
variant="system"
value={undefined}
value="system"
label={t("theme_system")}
defaultChecked={user.appTheme === null}
register={userAppThemeFormMethods.register}
@@ -244,17 +250,21 @@ const AppearanceView = ({
</div>
<Form
form={userThemeFormMethods}
handleSubmit={(values) => {
handleSubmit={({ theme }) => {
if (theme === "light" || theme === "dark") {
mutation.mutate({
theme,
});
return;
}
mutation.mutate({
// Radio values don't support null as values, therefore we convert an empty string
// back to null here.
theme: values.theme === "" ? null : values.theme,
theme: null,
});
}}>
<div className="border-subtle flex flex-col justify-between border-x px-6 py-8 sm:flex-row">
<ThemeLabel
variant="system"
value={undefined}
value="system"
label={t("theme_system")}
defaultChecked={user.theme === null}
register={userThemeFormMethods.register}
@@ -58,7 +58,6 @@ const ConferencingView = () => {
query={query}
customLoader={<SkeletonLoader />}
success={({ data }) => {
console.log(data);
if (!data.items.length) {
return (
<EmptyScreen
@@ -4,6 +4,7 @@ import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
import { useState, useEffect } from "react";
import Shell from "@calcom/features/shell/Shell";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { showToast } from "@calcom/ui";
import {
@@ -22,6 +23,7 @@ import { PlatformPricing } from "@components/settings/platform/pricing/platform-
const queryClient = new QueryClient();
export default function Platform() {
const { t } = useLocale();
const [initialClientId, setInitialClientId] = useState("");
const [initialClientName, setInitialClientName] = useState("");
@@ -75,11 +77,12 @@ export default function Platform() {
<QueryClientProvider client={queryClient}>
<div>
<Shell
heading="Platform"
title="Platform"
heading={t("platform")}
subtitle={t("platform_description")}
title={t("platform")}
description={t("platform_description")}
hideHeadingOnMobile
withoutMain={false}
subtitle="Manage everything related to platform."
isPlatformUser={true}>
<HelpCards />
<OAuthClientsList oauthClients={data} isDeleting={isDeleting} handleDelete={handleDelete} />
+3 -3
View File
@@ -19,10 +19,10 @@ function Teams(props: PageProps) {
<Shell
withoutMain={false}
heading={t("teams")}
title="Teams"
description="Create and manage teams to use collaborative features."
hideHeadingOnMobile
subtitle={t("create_manage_teams_collaborative")}
title={t("teams")}
description={t("create_manage_teams_collaborative")}
hideHeadingOnMobile
CTA={
(!user.organizationId || user.organization.isOrgAdmin) && (
<Button
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@calcom/web",
"version": "4.5.8",
"version": "4.5.10",
"private": true,
"scripts": {
"analyze": "ANALYZE=true next build",
+1 -1
View File
@@ -33,7 +33,7 @@ export default function Custom404() {
const links = [
{
title: "Enterprise",
title: t("enterprise"),
description: "Learn more about organizations and subdomains in our enterprise plan.",
icon: "shield" as const,
href: `${WEBSITE_URL}/enterprise`,
+7 -5
View File
@@ -1,7 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import { updateQuantitySubscriptionFromStripe } from "@calcom/features/ee/teams/lib/payments";
import { TeamBilling } from "@calcom/ee/billing/teams";
import prisma from "@calcom/prisma";
const querySchema = z.object({
@@ -32,6 +32,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
},
select: {
id: true,
metadata: true,
isOrganization: true,
parentId: true,
},
skip: pageNumber * pageSize,
take: pageSize,
@@ -41,10 +44,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
break;
}
for (const team of teams) {
await updateQuantitySubscriptionFromStripe(team.id);
await delay(100); // Adjust the delay as needed to avoid rate limiting
}
const teamsBilling = TeamBilling.initMany(teams);
const teamBillingPromises = teamsBilling.map((teamBilling) => teamBilling.updateQuantity());
await Promise.allSettled(teamBillingPromises);
pageNumber++;
}
+7
View File
@@ -0,0 +1,7 @@
export const config = {
api: {
bodyParser: false,
},
};
export { default } from "@calcom/features/ee/billing/api/webhook";
+4
View File
@@ -3,6 +3,8 @@
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { getServerSideProps } from "@server/lib/setup/getServerSideProps";
import type { PageProps } from "~/auth/setup-view";
@@ -17,6 +19,8 @@ const Page = (props: PageProps) => {
</>
);
};
Page.PageWrapper = PageWrapper;
export default Page;
export { getServerSideProps };
+92 -8
View File
@@ -1,10 +1,70 @@
import { expect } from "@playwright/test";
import { testBothFutureAndLegacyRoutes } from "playwright/lib/future-legacy-routes";
import { test } from "./lib/fixtures";
testBothFutureAndLegacyRoutes.describe("Change Theme Test", () => {
test("change theme to dark", async ({ page, users }) => {
test.describe("Change App Theme Test", () => {
test("change app theme to dark", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.click('[data-testid="appTheme-dark"]');
await page.click('[data-testid="update-app-theme-btn"]');
const toast = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast).toBeTruthy();
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("dark");
const themeValue = await page.evaluate(() => localStorage.getItem("app-theme"));
expect(themeValue).toBe("dark");
});
test("change app theme to light", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.click('[data-testid="appTheme-light"]');
await page.click('[data-testid="update-app-theme-btn"]');
const toast = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast).toBeTruthy();
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("light");
const themeValue = await page.evaluate(() => localStorage.getItem("app-theme"));
expect(themeValue).toBe("light");
});
test("change app theme to system", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.click('[data-testid="appTheme-light"]');
await page.click('[data-testid="update-app-theme-btn"]');
const toast1 = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast1).toBeTruthy();
await page.click('[data-testid="appTheme-system"]');
await page.click('[data-testid="update-app-theme-btn"]');
const toast2 = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast2).toBeTruthy();
await page.waitForTimeout(3000);
const themeValue = await page.evaluate(() => localStorage.getItem("app-theme"));
expect(themeValue).toBe("system");
const systemTheme = await page.evaluate(() => {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
});
expect(await page.getAttribute("html", "class")).toContain(systemTheme);
});
});
test.describe("Change Booking Page Theme Test", () => {
test("change booking page theme to dark", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
@@ -19,11 +79,11 @@ testBothFutureAndLegacyRoutes.describe("Change Theme Test", () => {
expect(toast).toBeTruthy();
//Go to the profile page and check if the theme is dark
await page.goto(`/${pro.username}`);
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("dark");
const htmlClass = await page.getAttribute("html", "class");
expect(htmlClass).toContain("dark");
});
test("change theme to light", async ({ page, users }) => {
test("change booking page theme to light", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
@@ -38,7 +98,31 @@ testBothFutureAndLegacyRoutes.describe("Change Theme Test", () => {
expect(toast).toBeTruthy();
//Go to the profile page and check if the theme is light
await page.goto(`/${pro.username}`);
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("light");
const htmlClass = await page.getAttribute("html", "class");
expect(htmlClass).toContain("light");
});
test("change booking page theme to system", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.click('[data-testid="theme-light"]');
await page.click('[data-testid="update-theme-btn"]');
const toast1 = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast1).toBeTruthy();
await page.click('[data-testid="theme-system"]');
await page.click('[data-testid="update-theme-btn"]');
const toast2 = await page.waitForSelector('[data-testid="toast-success"]');
expect(toast2).toBeTruthy();
await page.goto(`/${pro.username}`);
const systemTheme = await page.evaluate(() => {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
});
expect(await page.getAttribute("html", "class")).toContain(systemTheme);
});
});
-2
View File
@@ -579,8 +579,6 @@ export const createUsersFixture = (
await updateChildrenEventTypes({
eventTypeId: teamEvent.id,
currentUserId: user.id,
hashedLink: "",
connectedLink: null,
oldEventType: {
team: null,
},
+8 -4
View File
@@ -26,12 +26,12 @@ test.describe("hash my url", () => {
// We wait for the page to load
await page.locator(".primary-navigation >> text=Advanced").click();
// ignore if it is already checked, and click if unchecked
const hashedLinkCheck = await page.locator('[data-testid="hashedLinkCheck"]');
const hashedLinkCheck = await page.locator('[data-testid="multiplePrivateLinksCheck"]');
await hashedLinkCheck.click();
// we wait for the hashedLink setting to load
const $url = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
const $url = await page.locator('//*[@data-testid="generated-hash-url-0"]').inputValue();
// click update
await page.locator('[data-testid="update-eventtype"]').press("Enter");
@@ -50,8 +50,12 @@ test.describe("hash my url", () => {
await page.locator("ul[data-testid=event-types] > li a").first().click();
// We wait for the page to load
await page.locator(".primary-navigation >> text=Advanced").click();
const hashedLinkCheck2 = await page.locator('[data-testid="multiplePrivateLinksCheck"]');
await hashedLinkCheck2.click();
// we wait for the hashedLink setting to load
const $newUrl = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
const $newUrl = await page.locator('//*[@data-testid="generated-hash-url-0"]').inputValue();
expect($url !== $newUrl).toBeTruthy();
// Ensure that private URL is enabled after modifying the event type.
@@ -63,7 +67,7 @@ test.describe("hash my url", () => {
action: () => page.locator("[data-testid=update-eventtype]").click(),
});
await page.locator(".primary-navigation >> text=Advanced").click();
const $url2 = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
const $url2 = await page.locator('//*[@data-testid="generated-hash-url-0"]').inputValue();
expect($url2.includes("somethingrandom")).toBeTruthy();
});
});
@@ -233,8 +233,8 @@ test.describe("Stripe integration skip true", () => {
// Select currency in dropdown
await page.getByTestId("stripe-currency-select").click();
await page.locator("#react-select-2-input").fill("mexi");
await page.locator("#react-select-2-option-81").click();
await page.getByTestId("stripe-currency-input").fill("mexi");
await page.getByTestId("select-option-mxn").click();
await page.getByTestId("update-eventtype").click();
@@ -467,8 +467,8 @@ test.describe("Stripe integration with the new app install flow skip false", ()
// Select currency in dropdown
await page.getByTestId("stripe-currency-select").click();
await page.locator("#react-select-2-input").fill("mexi");
await page.locator("#react-select-2-option-81").click();
await page.getByTestId("stripe-currency-input").fill("mexi");
await page.getByTestId("select-option-mxn").click();
await page.click(`[data-testid="configure-step-save"]`);
await page.waitForURL(`event-types`);
+1 -1
View File
@@ -437,7 +437,7 @@ test.describe("authorized user sees changed translations (de->ar)", async () =>
await page.waitForLoadState("domcontentloaded");
await page.locator(".bg-default > div > div:nth-child(2)").first().click();
await page.locator("#react-select-2-option-0").click();
await page.getByTestId("select-option-ar").click();
await page.getByRole("button", { name: "Aktualisieren" }).click();
@@ -147,9 +147,11 @@ test.describe("Unpublished Organization Redirection", () => {
},
data: {
hashedLink: {
create: {
link: generateHashedLink(eventType.id),
},
create: [
{
link: generateHashedLink(eventType.id),
},
],
},
},
include: {
@@ -158,7 +160,7 @@ test.describe("Unpublished Organization Redirection", () => {
});
await doOnOrgDomain({ page, orgSlug }, async () => {
await page.goto(`/d/${privateEvent.hashedLink?.link}/${privateEvent.slug}`);
await page.goto(`/d/${privateEvent.hashedLink[0]?.link}/${privateEvent.slug}`);
// Expect the empty screen, indicating the event is inaccessible.
await expect(page.getByTestId("empty-screen")).toBeVisible();
@@ -180,9 +182,11 @@ test.describe("Unpublished Organization Redirection", () => {
},
data: {
hashedLink: {
create: {
link: generateHashedLink(eventType.id),
},
create: [
{
link: generateHashedLink(eventType.id),
},
],
},
},
include: {
@@ -191,7 +195,7 @@ test.describe("Unpublished Organization Redirection", () => {
});
await doOnOrgDomain({ page, orgSlug }, async () => {
await page.goto(`/d/${privateEvent.hashedLink?.link}/${privateEvent.slug}?orgRedirection=true`);
await page.goto(`/d/${privateEvent.hashedLink[0]?.link}/${privateEvent.slug}?orgRedirection=true`);
// Verify that the event page is visible.
await expect(page.getByTestId("event-title")).toBeVisible();
+10 -10
View File
@@ -121,7 +121,7 @@ test.describe("Payment app", () => {
await page.getByPlaceholder("Price").fill("150");
await page.getByTestId("paypal-currency-select").click();
await page.locator("#react-select-2-option-13").click();
await page.getByTestId("select-option-MXN").click();
await page.getByTestId("paypal-payment-option-select").click();
@@ -314,13 +314,13 @@ test.describe("Payment app", () => {
await page.goto(`event-types/${paymentEvent.id}?tabName=apps`);
await page.locator("[data-testid='paypal-app-switch']").click();
await page.locator("[data-testid='paypal-price-input']").fill("100");
await page.locator("[data-testid='paypal-currency-select']").first().click();
await page.locator("#react-select-2-option-13").click();
await page.getByTestId("paypal-app-switch").click();
await page.getByTestId("paypal-price-input").fill("100");
await page.getByTestId("paypal-currency-select").first().click();
await page.getByTestId("select-option-MXN").click();
// await page.locator(".mb-1 > .bg-default > div > div:nth-child(2)").first().click();
// await page.getByText("$MXNCurrencyMexican pesoPayment option").click();
await page.locator("[data-testid='update-eventtype']").click();
await page.getByTestId("update-eventtype").click();
// Need to wait for the DB to be updated
await page.waitForResponse((res) => res.url().includes("update") && res.status() === 200);
@@ -336,10 +336,10 @@ test.describe("Payment app", () => {
expect(paypalPrice?.price).toEqual(10000);
await page.locator("[data-testid='paypal-app-switch']").click();
await page.locator("[data-testid='stripe-app-switch']").click();
await page.locator("[data-testid='stripe-price-input']").fill("200");
await page.locator("[data-testid='update-eventtype']").click();
await page.getByTestId("paypal-app-switch").click();
await page.getByTestId("stripe-app-switch").click();
await page.getByTestId("stripe-price-input").fill("200");
await page.getByTestId("update-eventtype").click();
// Need to wait for the DB to be updated
await page.waitForResponse((res) => res.url().includes("update") && res.status() === 200);
+2 -1
View File
@@ -1,4 +1,5 @@
import { expect, Page } from "@playwright/test";
import type { Page } from "@playwright/test";
import { expect } from "@playwright/test";
import { randomBytes } from "crypto";
import { APP_NAME, IS_PREMIUM_USERNAME_ENABLED, IS_MAILHOG_ENABLED } from "@calcom/lib/constants";
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "نسخ الرابط الخاص",
"copy_private_link_to_event": "نسخ الرابط الخاص للحدث",
"private_link_description": "إنشاء عنوان URL خاص لمشاركته دون الكشف عن اسم المستخدم الخاص بك في {{appName}}",
"multiple_private_links_title": "روابط خاصة",
"multiple_private_links_description": "إنشاء روابط خاصة دون الكشف عن اسم المستخدم، والتي سيتم تدميرها بمجرد استخدامها",
"add_a_multiple_private_link": "إضافة رابط جديد",
"multiple_private_link_copied": "تم نسخ الرابط الخاص",
"invitees_can_schedule": "يمكن للمدعوين الجدولة",
"date_range": "الفترة الزمنية",
"calendar_days": "أيام التقويم",
"business_days": "أيام العمل",
"set_address_place": "تعيين عنوان أو مكان",
"set_link_meeting": "تعيين رابطًا للاجتماع",
"managed_event_field_parent_control_disabled": "لا يمكن تبديله. يمكن فتحه فقط لأنواع الأحداث الفرعية",
"cal_invitee_phone_number_scheduling": "سيطلب {{appName}} من المدعو لديك إدخال رقم الهاتف قبل الجدولة.",
"cal_provide_google_meet_location": "سيوفر {{appName}} رابطًا لـ Google Meet.",
"cal_provide_zoom_meeting_url": "سيوفر {{appName}} رابطًا للاجتماع عبر Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "إرسال رسائل قصيرة للحضور للتذكير قبل ساعة من بدء الحدث",
"workflow_example_5": "إرسال رسالة قصيرة مخصصة للحضور عند إعادة جدولة الحدث",
"workflow_example_6": "إرسال بريد إلكتروني مخصص للمضيف عندما يتم حجز حدث جديد",
"count_managed_to_limit": "تضمين عدد الحجوزات من أنواع الفعاليات المُدارة",
"welcome_to_cal_header": "مرحبًا بك في {{appName}}!",
"edit_form_later_subtitle": "ستتمكن من تعديل هذا لاحقًا.",
"connect_calendar_later": "سأقوم بربط التقويم لاحقًا",
@@ -2043,7 +2049,8 @@
"error_charging_card": "حدثت مشكلة في خصم رسوم عدم الحضور. يرجى المحاولة مرة أخرى لاحقًا.",
"collect_no_show_fee": "تحصيل رسوم عدم الحضور",
"no_show_fee_charged": "تم تحصيل رسوم عدم حضور",
"insights": "Insights",
"insights": "رؤى",
"routing_forms": "نماذج التوجيه",
"testing_workflow_info_message": "عند اختبار سير العمل هذا، يجب أن تدرك أنه لا يمكن جدولة رسائل البريد الإلكتروني والرسائل القصيرة إلا قبل ساعة واحدة على الأقل",
"insights_no_data_found_for_filter": "لم يتم العثور على بيانات لعامل التصفية المحدد أو التواريخ المحددة.",
"acknowledge_booking_no_show_fee": "أقر بأنه إذا لم أحضر هذا الحدث فسيتم سحب رسوم عدم حضور من بطاقتي تبلغ {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "إعداد منظمتك",
"set_up_your_platform_organization": "إعداد منصتك",
"organizations_description": "المنظمات هي بيئات مشتركة حيث يمكن للفرق إنشاء أنواع الأحداث المشتركة والتطبيقات ومهام سير العمل والمزيد.",
"platform": "المنصة",
"platform_description": "إدارة كل ما يتعلق بالمنصة.",
"platform_organization_description": "تتيح لك منصة Cal.com دمج الجدولة بسهولة في تطبيقك باستخدام واجهات برمجة التطبيقات والعناصر.",
"must_enter_organization_name": "يجب إدخال اسم المنظمة",
"must_enter_organization_admin_email": "يجب إدخال عنوان البريد الإلكتروني لمنظمتك",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "أضف بطاقة ائتمان واحدة لدفع جميع اشتراكات فريقك",
"advanced_managed_events": "أنواع الأحداث المدارة المتقدمة",
"advanced_managed_events_description": "أضف بطاقة ائتمان واحدة لدفع جميع اشتراكات فريقك",
"enterprise": "المؤسسة",
"enterprise_description": "قم بالترقية إلى Enterprise لإنشاء مؤسستك",
"create_your_org": "أنشئ مؤسستك",
"create_your_org_description": "قم بالترقية إلى المنظمات واحصل على نطاق فرعي، وفوترة موحدة، ورؤى، وتخصيص واسع النطاق والمزيد",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "تعطيل الإدخال إذا كان معرف URL مملوء مسبقًا",
"booking_limits": "حدود الحجز",
"booking_limits_team_description": "حدود الحجز لأعضاء الفريق عبر جميع أنواع فعاليات الفريق",
"limit_team_booking_frequency_description": "حدد عدد المرات التي يمكن فيها حجز الأعضاء عبر جميع أنواع فعاليات الفريق (الجماعية وround-robin)",
"limit_team_booking_frequency_description": "تحديد عدد المرات التي يمكن فيها حجز الأعضاء عبر جميع أنواع فعاليات الفريق",
"booking_limits_updated_successfully": "تم تحديث حدود الحجز بنجاح",
"you_are_unauthorized_to_make_this_change_to_the_booking": "أنت غير مخول لإجراء هذا التغيير على الحجز",
"matching_members": "الأعضاء المطابقون",
"no_matching_members": "لا يوجد أعضاء مطابقون. سيتم الرجوع إلى استخدام أعضاء الفريق المعينين لنوع الحدث.",
"hide_calendar_event_details": "إخفاء تفاصيل الأحداث في التقويمات المشتركة",
"description_hide_calendar_event_details": "عند مشاركة التقويم، تكون الأحداث مرئية للقراء ولكن تفاصيلها تكون مخفية عن أولئك الذين ليس لديهم صلاحية الكتابة.",
"last_number_of_days": "آخر {{count}} يوم",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Şəxsi linki kopyala",
"copy_private_link_to_event": "Tədbirə şəxsi linki kopyala",
"private_link_description": "Öz {{appName}} istifadəçi adınızı açıqlamadan paylaşmaq üçün şəxsi URL yaradın",
"multiple_private_links_title": "Şəxsi Keçidlər",
"multiple_private_links_description": "İstifadəçi adını açıqlamadan şəxsi URL-lər yaradın, istifadə edildikdən sonra məhv ediləcək",
"add_a_multiple_private_link": "Yeni keçid əlavə edin",
"multiple_private_link_copied": "Şəxsi keçid kopyalandı",
"invitees_can_schedule": "Dəvətlilər cədvəl qura bilər",
"date_range": "Tarix Aralığı",
"calendar_days": "təqvim günləri",
"business_days": "iş günləri",
"set_address_place": "Ünvan və ya yer təyin edin",
"set_link_meeting": "Görüş üçün link təyin edin",
"managed_event_field_parent_control_disabled": "Dəyişdirilə bilməz. Yalnız uşaq tədbir növləri üçün açılabilir",
"cal_invitee_phone_number_scheduling": "{{appName}} dəvətlilərinizdən cədvəl qurmazdan əvvəl telefon nömrəsi daxil etmələrini istəyəcək.",
"cal_provide_google_meet_location": "{{appName}} Google Meet yeri təmin edəcək.",
"cal_provide_zoom_meeting_url": "{{appName}} Zoom görüş URL-i təmin edəcək.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Tədbir başlamazdan 1 saat əvvəl iştirakçıya e-poçt xatırlatma göndərin",
"workflow_example_5": "Tədbir təxirə salındıqda ev sahibinə xüsusi e-poçt göndərin",
"workflow_example_6": "Yeni tədbir sifariş edildikdə ev sahibinə xüsusi SMS göndərin",
"count_managed_to_limit": "İdarə olunan tədbir növlərindən rezervasiya saylarını daxil edin",
"welcome_to_cal_header": "{{appName}}-a xoş gəlmisiniz!",
"edit_form_later_subtitle": "Bunu sonra redaktə edə biləcəksiniz.",
"connect_calendar_later": "Təqvimimi sonra qoşacağam",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Gəlməmə haqqını toplayın",
"no_show_fee_charged": "Gəlməmə haqqı tutuldu",
"insights": "Görüşlər",
"routing_forms": "Marşrutlaşdırma Formları",
"testing_workflow_info_message": "Bu iş axınını sınaqdan keçirərkən, e-poçtların və SMS-lərin ən azı 1 saat əvvəl planlaşdırıla biləcəyini unutmayın",
"insights_no_data_found_for_filter": "Seçilmiş filtr və ya tarixlər üçün məlumat tapılmadı.",
"acknowledge_booking_no_show_fee": "Bu tədbirə qatılmasam, kartıma {{amount, currency}} gəlməmə haqqı tətbiq olunacağını qəbul edirəm.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Təşkilatınızı qurun",
"set_up_your_platform_organization": "Platformanızı qurun",
"organizations_description": "Təşkilatlar komandaların paylaşılan tədbir növləri, tətbiqlər, iş axınları və daha çoxunu yarada biləcəyi paylaşılan mühitlərdir.",
"platform": "Platforma",
"platform_description": "Platforma ilə bağlı hər şeyi idarə edin.",
"platform_organization_description": "Cal.com Platforması, platforma API-ləri və atomları istifadə edərək planlaşdırmanı tətbiqinizə asanlıqla inteqrasiya etməyə imkan verir.",
"must_enter_organization_name": "Təşkilat adını daxil etməlisiniz",
"must_enter_organization_admin_email": "Təşkilatınızın e-poçt ünvanını daxil etməlisiniz",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Bütün komandanızın abunəliklərini ödəmək üçün bir kredit kartı əlavə edin",
"advanced_managed_events": "İrəli Səviyyəli İdarə Edilən Tədbir Növləri",
"advanced_managed_events_description": "Bütün komandanızın abunəliklərini ödəmək üçün bir kredit kartı əlavə edin",
"enterprise": "Müəssisə",
"enterprise_description": "Təşkilatınızı yaratmaq üçün Enterprise-ə yüksəldin",
"create_your_org": "Təşkilatınızı Yaradın",
"create_your_org_description": "Təşkilatlara yüksəlin və subdomen, birləşdirilmiş ödəniş, Göstəricilər, geniş ağ etiketləmə və daha çoxunu əldə edin",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "URL identifikatoru əvvəlcədən doldurulubsa girişi deaktiv et",
"booking_limits": "Rezervasiya Məhdudiyyətləri",
"booking_limits_team_description": "Bütün komanda tədbir növləri üzrə komanda üzvləri üçün rezervasiya məhdudiyyətləri",
"limit_team_booking_frequency_description": "Komanda üzvlərinin bütün komanda tədbir növləri (kollektiv və round-robin) üzrə neçə dəfə rezervasiya edilə biləcəyini məhdudlaşdırın",
"limit_team_booking_frequency_description": "Üzvlərin bütün komanda tədbir növləri üzrə neçə dəfə rezervasiya edilə biləcəyini məhdudlaşdırın",
"booking_limits_updated_successfully": "Rezervasiya məhdudiyyətləri uğurla yeniləndi",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Bu dəyişikliyi etmək üçün səlahiyyətiniz yoxdur",
"matching_members": "Uyğun üzvlər",
"no_matching_members": "Uyğun üzvlər yoxdur. Bu halda tədbir növünə təyin edilmiş komanda üzvləri istifadə olunacaq.",
"hide_calendar_event_details": "Təqvim hadisə detallarını gizlət",
"description_hide_calendar_event_details": "Təqvim paylaşıldıqda, hadisələr oxucular üçün görünür, lakin yazma icazəsi olmayanlar üçün detallar gizlədilir.",
"last_number_of_days": "son {{count}} gün",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Zkopírovat soukromý odkaz",
"copy_private_link_to_event": "Zkopírovat soukromý odkaz na událost",
"private_link_description": "Vygenerujte soukromou adresu URL, kterou budete sdílet, aniž byste odhalili své uživatelské jméno ve službě {{appName}}",
"multiple_private_links_title": "Soukromé odkazy",
"multiple_private_links_description": "Vytvořte soukromé URL adresy bez odhalení uživatelského jména, které budou po použití zničeny",
"add_a_multiple_private_link": "Přidat nový odkaz",
"multiple_private_link_copied": "Soukromý odkaz zkopírován",
"invitees_can_schedule": "Pozvaní mohou plánovat",
"date_range": "Časové rozmezí",
"calendar_days": "kalendářních dní",
"business_days": "pracovních dní",
"set_address_place": "Zadejte adresu nebo místo",
"set_link_meeting": "Poslat odkaz na schůzku",
"managed_event_field_parent_control_disabled": "Nelze přepnout. Lze odemknout pouze pro podtypy událostí",
"cal_invitee_phone_number_scheduling": "{{appName}} vyzve pozvaného, aby před naplánováním zadal telefonní číslo.",
"cal_provide_google_meet_location": "{{appName}} poskytne místo Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} poskytne URL Zoom meetingu.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Odeslat účastníkovi upomínku 1 hodinu před začátkem akce",
"workflow_example_5": "Odeslat hostiteli vlastní e-mail, pokud je událost přeložena na jiný termín",
"workflow_example_6": "Odeslat hostiteli vlastní SMS, pokud je rezervována nová událost",
"count_managed_to_limit": "Zahrnout počty rezervací ze spravovaných typů událostí",
"welcome_to_cal_header": "Vítá vás {{appName}}!",
"edit_form_later_subtitle": "Toto budete moci upravit později.",
"connect_calendar_later": "Připojím svůj kalendář později",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Při strhávání poplatku za nedostavení se došlo k chybě. Zkuste to později.",
"collect_no_show_fee": "Vybrat poplatek za nedostavení se",
"no_show_fee_charged": "Poplatek za nedostavení se stržen",
"insights": "Insights",
"insights": "Přehledy",
"routing_forms": "Směrovací formuláře",
"testing_workflow_info_message": "Při testování tohoto pracovního postupu mějte na paměti, že e-maily a SMS lze naplánovat pouze nejméně 1 hodinu předem.",
"insights_no_data_found_for_filter": "Pro vybraný filtr nebo vybraná data nebyla nalezena žádná data.",
"acknowledge_booking_no_show_fee": "Beru na vědomí, že pokud se této události nezúčastním, bude z mé karty stržen poplatek za nedostavení se ve výši {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Nastavení organizace",
"set_up_your_platform_organization": "Nastavte svou platformu",
"organizations_description": "Organizace jsou sdílená prostředí, ve kterých mohou týmy vytvářet sdílené typy událostí, aplikace, pracovní postupy a mnoho dalšího.",
"platform": "Platforma",
"platform_description": "Spravujte vše, co souvisí s platformou.",
"platform_organization_description": "Platforma Cal.com vám umožňuje snadno integrovat plánování do vaší aplikace pomocí platformových API a atomů.",
"must_enter_organization_name": "Je nutné zadat název organizace",
"must_enter_organization_admin_email": "Je nutné zadat e-mailovou adresu organizace",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Přidejte jednu kreditní kartu pro platby za všechny předplatné vašeho týmu",
"advanced_managed_events": "Pokročilé spravované typy událostí",
"advanced_managed_events_description": "Přidejte jednu kreditní kartu pro platbu všech předplatných vašeho týmu",
"enterprise": "Podnik",
"enterprise_description": "Upgradujte na Enterprise a vytvořte svou organizaci",
"create_your_org": "Vytvořte svou organizaci",
"create_your_org_description": "Upgradujte na Organizace a získejte subdoménu, sjednocené fakturace, Insights, rozsáhlé whitelabeling a další",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Zakázat vstup, pokud je identifikátor URL předvyplněn",
"booking_limits": "Limity rezervací",
"booking_limits_team_description": "Limity rezervací pro členy týmu napříč všemi typy týmových událostí",
"limit_team_booking_frequency_description": "Omezte, kolikrát mohou být členové rezervováni napříč všemi typy týmových událostí (kolektivní a round-robin)",
"limit_team_booking_frequency_description": "Omezit, kolikrát mohou být členové rezervováni napříč všemi týmovými typy událostí",
"booking_limits_updated_successfully": "Limity rezervací byly úspěšně aktualizovány",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Nemáte oprávnění provést tuto změnu v rezervaci",
"matching_members": "Odpovídající členové",
"no_matching_members": "Žádní odpovídající členové. Bude použito záložní řešení s členy týmu přiřazenými k typu události.",
"hide_calendar_event_details": "Skrýt podrobnosti událostí v kalendáři na sdílených kalendářích",
"description_hide_calendar_event_details": "Když je kalendář sdílen, události jsou viditelné pro čtenáře, ale jejich podrobnosti jsou skryty pro ty, kteří nemají přístup k úpravám.",
"last_number_of_days": "posledních {{count}} dní",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Kopiér privat link",
"copy_private_link_to_event": "Kopiér privat link til begivenhed",
"private_link_description": "Generer en privat URL til deling uden at afsløre dit {{appName}} brugernavn",
"multiple_private_links_title": "Private links",
"multiple_private_links_description": "Generer private URL'er uden at afsløre brugernavnet, som vil blive slettet efter brug",
"add_a_multiple_private_link": "Tilføj nyt link",
"multiple_private_link_copied": "Privat link kopieret",
"invitees_can_schedule": "Inviterede kan planlægge",
"date_range": "Datointerval",
"calendar_days": "kalenderdage",
"business_days": "hverdage",
"set_address_place": "Angiv en adresse eller et sted",
"set_link_meeting": "Angiv et link til mødet",
"managed_event_field_parent_control_disabled": "Kan ikke aktiveres. Det kan kun låses op for underbegivenhedstyper",
"cal_invitee_phone_number_scheduling": "{{appName}} vil bede din inviterede om at indtaste et telefonnummer før planlægning.",
"cal_provide_google_meet_location": "{{appName}} vil angive en Google Meet placering.",
"cal_provide_zoom_meeting_url": "{{appName}} angiver en URL-adresse for Zoom-mødet.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Send e-mail påmindelse til deltager 1 time før begivenheder starter",
"workflow_example_5": "Send brugerdefineret e-mail til vært når begivenheden omlægges",
"workflow_example_6": "Send brugerdefineret SMS til vært når ny begivenhed bookes",
"count_managed_to_limit": "Inkluder bookingantal fra administrerede begivenhedstyper",
"welcome_to_cal_header": "Velkommen til {{appName}}!",
"edit_form_later_subtitle": "Du vil kunne redigere dette senere.",
"connect_calendar_later": "Jeg tilslutter min kalender senere",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Opkræv gebyr for udeblivelse",
"no_show_fee_charged": "Gebyr for udeblivelse opkrævet",
"insights": "Indsigter",
"routing_forms": "Ruteformularer",
"testing_workflow_info_message": "Når du tester denne arbejdsgang, skal du være opmærksom på, at e-mails og SMS'er kun kan planlægges mindst 1 time i forvejen",
"insights_no_data_found_for_filter": "Ingen data fundet for det valgte filter eller de valgte datoer.",
"acknowledge_booking_no_show_fee": "Jeg anerkender, at hvis jeg ikke deltager i denne begivenhed, vil et gebyr for udeblivelse på {{amount, currency}} blive opkrævet på mit kort.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Opsæt din organisation",
"set_up_your_platform_organization": "Opsæt din platform",
"organizations_description": "Organisationer er delte miljøer, hvor teams kan oprette delte begivenhedstyper, apps, arbejdsgange og mere.",
"platform": "Platform",
"platform_description": "Administrer alt relateret til platformen.",
"platform_organization_description": "Cal.com Platform lader dig integrere planlægning problemfrit i din app ved hjælp af platformens API'er og atomer.",
"must_enter_organization_name": "Du skal indtaste et organisationsnavn",
"must_enter_organization_admin_email": "Du skal indtaste din organisations emailadresse",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Tilføj et enkelt kreditkort for at betale for alle dine teams' abonnementer",
"advanced_managed_events": "Avancerede Administrerede Begivenhedstyper",
"advanced_managed_events_description": "Tilføj et enkelt kreditkort for at betale for alle dine teams' abonnementer",
"enterprise": "Virksomhed",
"enterprise_description": "Opgrader til Enterprise for at oprette din organisation",
"create_your_org": "Opret din Organisation",
"create_your_org_description": "Opgrader til Organisationer og få et subdomæne, samlet fakturering, Insights, omfattende whitelabeling og mere",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Deaktiver input, hvis URL-identifikatoren er udfyldt på forhånd",
"booking_limits": "Bookinggrænser",
"booking_limits_team_description": "Bookinggrænser for teammedlemmer på tværs af alle teambegivenhedstyper",
"limit_team_booking_frequency_description": "Begræns, hvor mange gange medlemmer kan bookes på tværs af alle teambegivenhedstyper (kollektiv og round-robin)",
"limit_team_booking_frequency_description": "Begræns, hvor mange gange medlemmer kan bookes på tværs af alle team-begivenhedstyper",
"booking_limits_updated_successfully": "Bookinggrænser opdateret med succes",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Du har ikke tilladelse til at foretage denne ændring i bookingen",
"matching_members": "Matchende medlemmer",
"no_matching_members": "Ingen matchende medlemmer. Det vil falde tilbage til at bruge de teammedlemmer, der er tildelt til begivenhedstypen.",
"hide_calendar_event_details": "Skjul kalenderbegivenhedsdetaljer på delte kalendere",
"description_hide_calendar_event_details": "Når en kalender deles, er begivenheder synlige for læsere, men deres detaljer er skjult for dem uden skriveadgang.",
"last_number_of_days": "sidste {{count}} dage",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Privaten Link kopieren",
"copy_private_link_to_event": "Privaten Link zum Ereignis kopieren",
"private_link_description": "Erzeugen Sie einen privaten Link, den Sie teilen können, ohne Ihren {{appName}}-Benutzername preiszugeben",
"multiple_private_links_title": "Private Links",
"multiple_private_links_description": "Generieren Sie private URLs ohne den Benutzernamen preiszugeben. Diese werden nach einmaliger Verwendung gelöscht",
"add_a_multiple_private_link": "Neuen Link hinzufügen",
"multiple_private_link_copied": "Privater Link kopiert",
"invitees_can_schedule": "Teilnehmende können folgendes buchen",
"date_range": "Datumszeitraum",
"calendar_days": "Kalendertage",
"business_days": "Werktage",
"set_address_place": "Adresse oder Ort festlegen",
"set_link_meeting": "Einen Link zum Termin setzen",
"managed_event_field_parent_control_disabled": "Kann nicht umgeschaltet werden. Kann nur für untergeordnete Ereignistypen freigeschaltet werden",
"cal_invitee_phone_number_scheduling": "{{appName}} wird Ihren Teilnehmer bitten, vor der Planung eine Telefonnummer einzugeben.",
"cal_provide_google_meet_location": "{{appName}} wird einen Google Meet Ort zur Verfügung stellen.",
"cal_provide_zoom_meeting_url": "{{appName}} wird eine Zoom Meeting URL zur Verfügung stellen.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Eine Erinnerung per SMS an die Teilnehmer verschicken, 24 Stunden bevor das Event startet",
"workflow_example_5": "Benutzerdefinierte E-Mail senden, wenn der Termin zum Moderieren neu geplant wird",
"workflow_example_6": "Benutzerdefinierte SMS senden, wenn der Termin zum Moderieren gebucht wird",
"count_managed_to_limit": "Buchungszahlen von verwalteten Ereignistypen einbeziehen",
"welcome_to_cal_header": "Willkommen bei {{appName}}!",
"edit_form_later_subtitle": "Sie können dies später bearbeiten.",
"connect_calendar_later": "Ich verbinde meinen Kalender später",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Beim Berechnen der Nichterscheinungsgebühr ist etwas schiefgelaufen. Bitte versuchen Sie es später erneut.",
"collect_no_show_fee": "Gebühr für das Nichterscheinen anfordern",
"no_show_fee_charged": "Gebühr für das Nichterscheinen berechnet",
"insights": "Insights",
"insights": "Erkenntnisse",
"routing_forms": "Weiterleitungsformulare",
"testing_workflow_info_message": "Bitte beachten Sie beim Testen dieses Workflows, dass E-Mails und SMS spätestens 1 Stunde im Voraus geplant werden können",
"insights_no_data_found_for_filter": "Keine Daten für den ausgewählten Filter oder das ausgewählte Datum gefunden.",
"acknowledge_booking_no_show_fee": "Ich bestätige, dass meiner Karte eine Gebühr von {{amount, currency}} berechnet wird, sofern ich nicht an diesem Ereignis teilnehme.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Ihre Organization einrichten",
"set_up_your_platform_organization": "Richten Sie Ihre Plattform ein",
"organizations_description": "Organizations sind geteilte Umgebungen, in denen Teams gemeinsame Termintypen, Apps, Workflows und mehr erstellen können.",
"platform": "Plattform",
"platform_description": "Verwalten Sie alles, was mit der Plattform zusammenhängt.",
"platform_organization_description": "Mit der Cal.com-Plattform können Sie die Terminplanung mühelos mit Hilfe von Plattform-APIs und -Atoms in Ihre App integrieren.",
"must_enter_organization_name": "Es muss ein Name für die Organization eingegeben werden",
"must_enter_organization_admin_email": "Sie müssen Ihre Organization-Mailadresse eingeben\n",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Fügen Sie eine einzige Kreditkarte hinzu, um alle Abos Ihres Teams zu bezahlen",
"advanced_managed_events": "Erweiterte verwaltete Ereignistypen",
"advanced_managed_events_description": "Fügen Sie eine einzige Kreditkarte hinzu, um alle Abonnements Ihres Teams zu bezahlen",
"enterprise": "Unternehmen",
"enterprise_description": "Upgraden Sie um Ihre Organisation zu erstellen",
"create_your_org": "Erstellen Sie Ihre Organisation",
"create_your_org_description": "Upgraden und erhalten Sie eine Subdomain, einheitliche Abrechnungen, Insights, umfangreiches Whitelabeling und mehr",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Eingabe deaktivieren, wenn die URL-Kennung vorausgefüllt ist",
"booking_limits": "Buchungslimits",
"booking_limits_team_description": "Buchungslimits für Teammitglieder über alle Team-Ereignistypen hinweg",
"limit_team_booking_frequency_description": "Begrenzen Sie, wie oft Mitglieder über alle Team-Ereignistypen hinweg (kollektiv und round-robin) gebucht werden können",
"limit_team_booking_frequency_description": "Begrenzen Sie, wie oft Mitglieder über alle Team-Ereignistypen hinweg gebucht werden können",
"booking_limits_updated_successfully": "Buchungslimits erfolgreich aktualisiert",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Sie sind nicht berechtigt, diese Änderung an der Buchung vorzunehmen",
"matching_members": "Passende Mitglieder",
"no_matching_members": "Keine passenden Mitglieder gefunden. Es wird auf die dem Ereignistyp zugewiesenen Teammitglieder zurückgegriffen.",
"hide_calendar_event_details": "Kalenderereignisdetails in geteilten Kalendern verbergen",
"description_hide_calendar_event_details": "Wenn ein Kalender geteilt wird, sind Ereignisse für Leser sichtbar, aber ihre Details bleiben für Personen ohne Schreibzugriff verborgen.",
"last_number_of_days": "letzte {{count}} Tage",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copy private link",
"copy_private_link_to_event": "Copy private link to event",
"private_link_description": "Generate a private URL to share without exposing your {{appName}} username",
"multiple_private_links_title": "Private Links",
"multiple_private_links_description": "Generate private URLs without exposing the username, which will be destroyed once used",
"add_a_multiple_private_link": "Add new link",
"multiple_private_link_copied": "Private link copied",
"invitees_can_schedule": "Invitees can schedule",
"date_range": "Date Range",
"calendar_days": "calendar days",
"business_days": "business days",
"set_address_place": "Set an address or place",
"set_link_meeting": "Set a link to the meeting",
"managed_event_field_parent_control_disabled": "Can't be toggled. It can only be unlocked for child event types",
"cal_invitee_phone_number_scheduling": "{{appName}} will ask your invitee to enter a phone number before scheduling.",
"cal_provide_google_meet_location": "{{appName}} will provide a Google Meet location.",
"cal_provide_zoom_meeting_url": "{{appName}} will provide a Zoom meeting URL.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Send email reminder 1 hour before events starts to attendee",
"workflow_example_5": "Send custom email when event is rescheduled to host",
"workflow_example_6": "Send custom SMS when new event is booked to host",
"count_managed_to_limit": "Include booking counts from managed event types",
"welcome_to_cal_header": "Welcome to {{appName}}!",
"edit_form_later_subtitle": "You’ll be able to edit this later.",
"connect_calendar_later": "I'll connect my calendar later",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Collect no-show fee",
"no_show_fee_charged": "No-show fee charged",
"insights": "Insights",
"routing_forms": "Routing Forms",
"testing_workflow_info_message": "When testing this workflow, be aware that Emails and SMS can only be scheduled at least 1 hour in advance",
"insights_no_data_found_for_filter": "No data found for the selected filter or selected dates.",
"acknowledge_booking_no_show_fee": "I acknowledge that if I do not attend this event that a {{amount, currency}} no show fee will be applied to my card.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Set up your organization",
"set_up_your_platform_organization": "Set up your platform",
"organizations_description": "Organizations are shared environments where teams can create shared event types, apps, workflows and more.",
"platform": "Platform",
"platform_description": "Manage everything related to platform.",
"platform_organization_description": "Cal.com Platform lets you integrate scheduling effortlessly into your app using platform apis and atoms.",
"must_enter_organization_name": "Must enter an organization name",
"must_enter_organization_admin_email": "Must enter your organization email address",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Add a single credit card to pay for all your team's subscriptions",
"advanced_managed_events": "Advanced Managed Event Types",
"advanced_managed_events_description": "Add a single credit card to pay for all your team's subscriptions",
"enterprise": "Enterprise",
"enterprise_description": "Upgrade to Enterprise to create your Organization",
"create_your_org": "Create your Organization",
"create_your_org_description": "Upgrade to Organizations and receive a subdomain, unified billing, Insights, extensive whitelabeling and more",
@@ -2616,9 +2626,11 @@
"disable_input_if_prefilled": "Disable input if the URL identifier is prefilled",
"booking_limits": "Booking Limits",
"booking_limits_team_description": "Booking limits for team members across all team event types",
"limit_team_booking_frequency_description": "Limit how many times members can be booked across all team event types (collective and round-robin)",
"limit_team_booking_frequency_description": "Limit how many times members can be booked across all team event types",
"booking_limits_updated_successfully": "Booking limits updated successfully",
"you_are_unauthorized_to_make_this_change_to_the_booking": "You are unauthorized to make this change to the booking",
"matching_members": "Matching members",
"no_matching_members": "No matching members. It will fallback to using the team members assigned to the event type.",
"hide_calendar_event_details": "Hide calendar event details on shared calendars",
"description_hide_calendar_event_details": "When a calendar is shared, events are visible to readers but their details are hidden from those without write access.",
"last_number_of_days": "last {{count}} days",
@@ -876,12 +876,17 @@
"copy_private_link": "Copiar enlace privado",
"copy_private_link_to_event": "Copiar enlace privado al evento",
"private_link_description": "Genera una URL privada para compartir sin exponer tu nombre de usuario de {{appName}}",
"multiple_private_links_title": "Enlaces Privados",
"multiple_private_links_description": "Genera URLs privadas sin exponer el nombre de usuario, las cuales se destruirán una vez utilizadas",
"add_a_multiple_private_link": "Agregar nuevo enlace",
"multiple_private_link_copied": "Enlace privado copiado",
"invitees_can_schedule": "Los invitados pueden programar",
"date_range": "Rango de fechas",
"calendar_days": "días calendario",
"business_days": "días hábiles",
"set_address_place": "Establecer una dirección o lugar",
"set_link_meeting": "Establecer un enlace para la reunión",
"managed_event_field_parent_control_disabled": "No se puede alternar. Solo se puede desbloquear para tipos de eventos secundarios",
"cal_invitee_phone_number_scheduling": "{{appName}} pedirá a tu invitado que ingrese un número de teléfono antes de programar.",
"cal_provide_google_meet_location": "{{appName}} proporcionará una ubicación de Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} proporcionará una URL de reunión de Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Enviar recordatorio por correo electrónico 1 hora antes de que comiencen los eventos al asistente",
"workflow_example_5": "Enviar correo electrónico personalizado cuando el evento se reprograma al anfitrión",
"workflow_example_6": "Enviar SMS personalizado cuando se reserva un nuevo evento al anfitrión",
"count_managed_to_limit": "Incluir el conteo de reservas de los tipos de eventos gestionados",
"welcome_to_cal_header": "¡Bienvenido a {{appName}}!",
"edit_form_later_subtitle": "Podrás editar esto más tarde.",
"connect_calendar_later": "Conectaré mi calendario más tarde",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Cobrar tarifa de no presentación",
"no_show_fee_charged": "Tarifa de no presentación cobrada",
"insights": "Perspectivas",
"routing_forms": "Formularios de Enrutamiento",
"testing_workflow_info_message": "Al probar este flujo de trabajo, tenga en cuenta que los correos electrónicos y SMS solo se pueden programar con al menos 1 hora de anticipación",
"insights_no_data_found_for_filter": "No se encontraron datos para el filtro o las fechas seleccionadas.",
"acknowledge_booking_no_show_fee": "Reconozco que si no asisto a este evento, se aplicará una tarifa de no presentación de {{amount, currency}} a mi tarjeta.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configura tu organización",
"set_up_your_platform_organization": "Configura tu plataforma",
"organizations_description": "Las organizaciones son entornos compartidos donde los equipos pueden crear tipos de eventos, aplicaciones, flujos de trabajo y más compartidos.",
"platform": "Plataforma",
"platform_description": "Gestiona todo lo relacionado con la plataforma.",
"platform_organization_description": "La plataforma de Cal.com te permite integrar la programación sin esfuerzo en tu aplicación utilizando APIs y átomos de la plataforma.",
"must_enter_organization_name": "Debes ingresar un nombre de organización",
"must_enter_organization_admin_email": "Debes ingresar la dirección de correo electrónico de tu organización",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Agrega una sola tarjeta de crédito para pagar todas las suscripciones de tu equipo",
"advanced_managed_events": "Tipos de Eventos Avanzados Gestionados",
"advanced_managed_events_description": "Agrega una sola tarjeta de crédito para pagar todas las suscripciones de tu equipo",
"enterprise": "Empresa",
"enterprise_description": "Actualiza a Enterprise para crear tu Organización",
"create_your_org": "Crea tu Organización",
"create_your_org_description": "Actualiza a Organizaciones y recibe un subdominio, facturación unificada, Insights, etiquetado blanco extensivo y más",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Desactivar entrada si el identificador de URL está prellenado",
"booking_limits": "Límites de Reservas",
"booking_limits_team_description": "Límites de reservas para los miembros del equipo en todos los tipos de eventos del equipo",
"limit_team_booking_frequency_description": "Limita cuántas veces se pueden reservar los miembros en todos los tipos de eventos del equipo (colectivos y round-robin)",
"limit_team_booking_frequency_description": "Limitar cuántas veces se puede reservar a los miembros en todos los tipos de eventos del equipo",
"booking_limits_updated_successfully": "Límites de reservas actualizados con éxito",
"you_are_unauthorized_to_make_this_change_to_the_booking": "No tienes autorización para realizar este cambio en la reserva",
"matching_members": "Miembros coincidentes",
"no_matching_members": "No hay miembros coincidentes. Se utilizarán los miembros del equipo asignados al tipo de evento como alternativa.",
"hide_calendar_event_details": "Ocultar detalles de eventos del calendario en calendarios compartidos",
"description_hide_calendar_event_details": "Cuando se comparte un calendario, los eventos son visibles para los lectores, pero sus detalles están ocultos para aquellos sin acceso de escritura.",
"last_number_of_days": "últimos {{count}} días",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copiar enlace privado",
"copy_private_link_to_event": "Copiar enlace privado al evento",
"private_link_description": "Generar una URL privada para compartir sin exponer su nombre de usuario de {{appName}}",
"multiple_private_links_title": "Enlaces privados",
"multiple_private_links_description": "Genera URLs privadas sin exponer el nombre de usuario, que se destruirán una vez utilizadas",
"add_a_multiple_private_link": "Agregar nuevo enlace",
"multiple_private_link_copied": "Enlace privado copiado",
"invitees_can_schedule": "Los invitados pueden programar",
"date_range": "Rango de Fechas",
"calendar_days": "Días del Calendário",
"business_days": "Días Laborales",
"set_address_place": "Establecer una dirección o un lugar",
"set_link_meeting": "Establecer un enlace a la reunión",
"managed_event_field_parent_control_disabled": "No se puede alternar. Solo se puede desbloquear para tipos de eventos secundarios",
"cal_invitee_phone_number_scheduling": "{{appName}} le pedirá a su invitado que introduzca un número de teléfono antes de agendar.",
"cal_provide_google_meet_location": "{{appName}} proporcionará una URL de reunión de Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} proporcionará una URL de reunión de Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Enviar recordatorio por correo electrónico al asistente, 1 hora antes de que el evento comience",
"workflow_example_5": "Enviar correo electrónico personalizado al anfitrión cuando se reprograme el evento",
"workflow_example_6": "Enviar SMS personalizado al anfitrión cuando se reserve un evento nuevo",
"count_managed_to_limit": "Incluir el conteo de reservas de los tipos de eventos gestionados",
"welcome_to_cal_header": "¡Bienvenido a {{appName}}!",
"edit_form_later_subtitle": "Podrá editar esto más tarde.",
"connect_calendar_later": "Conectaré mi calendario más tarde",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Algo salió mal al cobrar la tarifa por no presentarse. Inténtelo de nuevo más tarde.",
"collect_no_show_fee": "Cobrar comisión por no presentarse",
"no_show_fee_charged": "Comisión por no presentarse cobrada",
"insights": "Insights",
"insights": "Perspectivas",
"routing_forms": "Formularios de enrutamiento",
"testing_workflow_info_message": "Al probar este flujo de trabajo, tenga en cuenta que los correos electrónicos y los SMS solo se pueden programar con al menos 1 hora de anticipación",
"insights_no_data_found_for_filter": "No se encontraron datos para el filtro seleccionado o las fechas seleccionadas.",
"acknowledge_booking_no_show_fee": "Reconozco que si no asisto a este evento, se aplicará a mi tarjeta una tarifa de {{amount, currency}} por no presentarme.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configure su organización",
"set_up_your_platform_organization": "Configura tu plataforma",
"organizations_description": "Las organizaciones son entornos compartidos donde los equipos pueden crear tipos de eventos, aplicaciones, flujos de trabajo compartidos y más.",
"platform": "Plataforma",
"platform_description": "Gestiona todo lo relacionado con la plataforma.",
"platform_organization_description": "Cal.com Platform te permite integrar la programación sin esfuerzo en tu aplicación utilizando APIs y átomos de la plataforma.",
"must_enter_organization_name": "Debe introducir el nombre de una organización",
"must_enter_organization_admin_email": "Debe introducir la dirección de correo electrónico de su organización",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Añade una sola tarjeta de crédito para pagar todas las suscripciones de tu equipo",
"advanced_managed_events": "Tipos de Eventos Avanzados Gestionados",
"advanced_managed_events_description": "Añade una sola tarjeta de crédito para pagar todas las suscripciones de tu equipo",
"enterprise": "Empresa",
"enterprise_description": "Actualiza a Enterprise para crear tu Organización",
"create_your_org": "Crea tu Organización",
"create_your_org_description": "Actualiza a Organizaciones y recibe un subdominio, facturación unificada, Insights, personalización extensa y más",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Desactivar entrada si el identificador de URL está prellenado",
"booking_limits": "Límites de Reservas",
"booking_limits_team_description": "Límites de reservas para los miembros del equipo en todos los tipos de eventos del equipo",
"limit_team_booking_frequency_description": "Limita cuántas veces se pueden reservar los miembros en todos los tipos de eventos del equipo (colectivos y round-robin)",
"limit_team_booking_frequency_description": "Limitar cuántas veces se pueden reservar los miembros en todos los tipos de eventos del equipo",
"booking_limits_updated_successfully": "Límites de reservas actualizados con éxito",
"you_are_unauthorized_to_make_this_change_to_the_booking": "No tienes autorización para realizar este cambio en la reserva",
"matching_members": "Miembros coincidentes",
"no_matching_members": "No hay miembros coincidentes. Se utilizarán los miembros del equipo asignados al tipo de evento como alternativa.",
"hide_calendar_event_details": "Ocultar detalles de eventos del calendario en calendarios compartidos",
"description_hide_calendar_event_details": "Cuando se comparte un calendario, los eventos son visibles para los lectores, pero sus detalles están ocultos para aquellos sin acceso de escritura.",
"last_number_of_days": "últimos {{count}} días",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Kopeeri privaatne link",
"copy_private_link_to_event": "Kopeeri sündmuse privaatne link",
"private_link_description": "Loo privaatne URL, mida jagate ilma oma {{appName}} kasutajanime paljastamata",
"multiple_private_links_title": "Privaatsed lingid",
"multiple_private_links_description": "Loo privaatsed URL-id ilma kasutajanime avalikustamata, mis hävitatakse pärast kasutamist",
"add_a_multiple_private_link": "Lisa uus link",
"multiple_private_link_copied": "Privaatne link kopeeritud",
"invitees_can_schedule": "Kutsutud saavad ajakava koostada",
"date_range": "Kuupäevavahemik",
"calendar_days": "kalendripäevad",
"business_days": "äripäevad",
"set_address_place": "Määra aadress või koht",
"set_link_meeting": "Määra koosoleku link",
"managed_event_field_parent_control_disabled": "Ei saa lülitada. Seda saab avada ainult alamürituste tüüpide jaoks",
"cal_invitee_phone_number_scheduling": "{{appName}} palub teie kutsutul enne ajastamist telefoninumbri sisestada.",
"cal_provide_google_meet_location": "{{appName}} pakub Google Meeti asukohta.",
"cal_provide_zoom_meeting_url": "{{appName}} annab Zoomi koosoleku URL-i.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Saada meili meeldetuletus 1 tund enne sündmuste algust osalejatele",
"workflow_example_5": "Saada kohandatud e-kiri, kui sündmus on korraldajale ümber ajastatud",
"workflow_example_6": "Saada kohandatud SMS, kui uus sündmus on hostile broneeritud",
"count_managed_to_limit": "Kaasa hallatavate sündmuste tüüpide broneeringute arv",
"welcome_to_cal_header": "Tere tulemast rakendusse {{appName}}!",
"edit_form_later_subtitle": "Saate seda hiljem muuta.",
"connect_calendar_later": "Ma ühendan oma kalendri hiljem",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Koguge mitteilmumise tasu",
"no_show_fee_charged": "Tasutakse mitteilmumise tasu",
"insights": "Teadmisi",
"routing_forms": "Suunamise vormid",
"testing_workflow_info_message": "Selle töövoo testimisel pidage meeles, et e-kirju ja SMS-e saab ajastada ainult vähemalt 1 tund ette",
"insights_no_data_found_for_filter": "Valitud filtri või valitud kuupäevade kohta andmeid ei leitud.",
"acknowledge_booking_no_show_fee": "Ma tean, et kui ma sellel üritusel ei osale, rakendatakse minu kaardile {{summa, valuuta}} mitteilmumise tasu.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Seadistage oma organisatsioon",
"set_up_your_platform_organization": "Seadista oma platvorm",
"organizations_description": "Organisatsioonid on jagatud keskkonnad, kus meeskonnad saavad luua jagatud sündmuste tüüpe, rakendusi, töövooge ja palju muud.",
"platform": "Platvorm",
"platform_description": "Halda kõike platvormiga seonduvat.",
"platform_organization_description": "Platvorm Cal.com võimaldab teil ajakava hõlpsalt oma rakendusse integreerida, kasutades platvormi apisid ja aatomeid.",
"must_enter_organization_name": "Tuleb sisestada organisatsiooni nimi",
"must_enter_organization_admin_email": "Tuleb sisestada oma organisatsiooni e-posti aadress",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Lisage kõigi oma meeskonna tellimuste eest tasumiseks üks krediitkaart",
"advanced_managed_events": "Täpsemad hallatud sündmuste tüübid",
"advanced_managed_events_description": "Lisage kõigi oma meeskonna tellimuste eest tasumiseks üks krediitkaart",
"enterprise": "Ettevõte",
"enterprise_description": "Oma organisatsiooni loomiseks minge üle ettevõttele",
"create_your_org": "Loo oma organisatsioon",
"create_your_org_description": "Minge üle organisatsioonidele ja saate alamdomeeni, ühtse arvelduse, ülevaate, ulatusliku valge sildistamise ja palju muud",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Keela sisend, kui URL-i identifikaator on eeltäidetud",
"booking_limits": "Broneerimispiirangud",
"booking_limits_team_description": "Meeskonnaliikmete broneerimispiirangud kõigi meeskonna sündmusetüüpide lõikes",
"limit_team_booking_frequency_description": "Piirake, mitu korda saab liikmeid broneerida kõigi meeskonna sündmusetüüpide lõikes (ühised ja round-robin)",
"limit_team_booking_frequency_description": "Piira, mitu korda saab meeskonnaliikmeid broneerida kõigi meeskonna sündmuste tüüpide lõikes",
"booking_limits_updated_successfully": "Broneerimispiirangud on edukalt uuendatud",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Teil puuduvad õigused selle broneeringu muutmiseks",
"matching_members": "Sobivad liikmed",
"no_matching_members": "Sobivaid liikmeid ei leitud. Kasutatakse sündmuse tüübile määratud meeskonnaliikmeid.",
"hide_calendar_event_details": "Peida kalendrisündmuste üksikasjad jagatud kalendrites",
"description_hide_calendar_event_details": "Kui kalender on jagatud, on sündmused lugejatele nähtavad, kuid nende üksikasjad on peidetud nende eest, kellel puudub kirjutamisõigus.",
"last_number_of_days": "viimased {{count}} päeva",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copier le lien privé",
"copy_private_link_to_event": "Copier le lien privé de l'événement",
"private_link_description": "Générez un lien privé à partager sans révéler votre nom d'utilisateur {{appName}}.",
"multiple_private_links_title": "Liens privés",
"multiple_private_links_description": "Générez des URL privées sans exposer le nom d'utilisateur, qui seront détruites une fois utilisées",
"add_a_multiple_private_link": "Ajouter un nouveau lien",
"multiple_private_link_copied": "Lien privé copié",
"invitees_can_schedule": "Les invités peuvent réserver",
"date_range": "Plage de dates",
"calendar_days": "jours calendaires",
"business_days": "jours ouvrés",
"set_address_place": "Définir une adresse ou un lieu",
"set_link_meeting": "Définir un lien vers le rendez-vous",
"managed_event_field_parent_control_disabled": "Ne peut pas être modifié. Il ne peut être déverrouillé que pour les types d'événements enfants",
"cal_invitee_phone_number_scheduling": "{{appName}} demandera à votre invité d'entrer un numéro de téléphone avant de faire une réservation.",
"cal_provide_google_meet_location": "{{appName}} fournira un lien Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} fournira un lien de rendez-vous Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Envoyer un rappel par e-mail aux participants 1 heure avant le début des événements",
"workflow_example_5": "Envoyer un e-mail personnalisé à l'hôte lorsque l'événement est replanifié",
"workflow_example_6": "Envoyer un SMS personnalisé à l'hôte lorsqu'un nouvel événement est réservé",
"count_managed_to_limit": "Inclure les compteurs de réservation des types d'événements gérés",
"welcome_to_cal_header": "Bienvenue sur {{appName}} !",
"edit_form_later_subtitle": "Vous pourrez modifier cela plus tard.",
"connect_calendar_later": "Je connecterai mon calendrier plus tard",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Percevoir les frais d'absence",
"no_show_fee_charged": "Frais d'absence facturés",
"insights": "Statistiques",
"routing_forms": "Formulaires de routage",
"testing_workflow_info_message": "Lors du test de ce workflow, sachez que les e-mails et les SMS ne peuvent être programmés qu'au moins 1 heure à l'avance",
"insights_no_data_found_for_filter": "Aucune donnée trouvée pour le filtre ou les dates sélectionnés.",
"acknowledge_booking_no_show_fee": "Je reconnais que si je ne participe pas à cet événement, des frais d'absence de {{amount, currency}} seront appliqués à ma carte.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configurer votre organisation",
"set_up_your_platform_organization": "Configurer votre plateforme",
"organizations_description": "Les organisations sont des environnements partagés dans lesquels les équipes peuvent créer des types d'événements partagés, des applications, des workflows, etc.",
"platform": "Plateforme",
"platform_description": "Gérez tout ce qui concerne la plateforme.",
"platform_organization_description": "La plateforme Cal.com vous permet d'intégrer sans effort la planification dans votre application en utilisant les API et atoms de la plateforme.",
"must_enter_organization_name": "Vous devez entrer un nom d'organisation",
"must_enter_organization_admin_email": "Vous devez entrer l'adresse e-mail de votre organisation",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Ajoutez une seule carte de crédit pour payer tous les abonnements de votre équipe",
"advanced_managed_events": "Types d'événements gérés avancés",
"advanced_managed_events_description": "Ajoutez une seule carte de crédit pour payer tous les abonnements de votre équipe",
"enterprise": "Entreprise",
"enterprise_description": "Passez en Entreprise pour créer votre organisation",
"create_your_org": "Créer votre organisation",
"create_your_org_description": "Passez en Organizations et recevez un sous-domaine, une facturation unifiée, des statistiques, un marquage blanc extensif et plus encore",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Désactiver la saisie si l'identifiant URL est prérempli",
"booking_limits": "Limites de réservation",
"booking_limits_team_description": "Limites de réservation pour les membres de l'équipe sur tous les types d'événements d'équipe",
"limit_team_booking_frequency_description": "Limitez le nombre de fois où les membres peuvent être réservés pour tous les types d'événements d'équipe (collectifs et round robin)",
"limit_team_booking_frequency_description": "Limiter le nombre de fois où les membres peuvent être réservés pour tous les types d'événements d'équipe",
"booking_limits_updated_successfully": "Limites de réservation mises à jour avec succès",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Vous n'êtes pas autorisé à apporter cette modification à la réservation",
"matching_members": "Membres correspondants",
"no_matching_members": "Aucun membre correspondant. Par défaut, les membres de l'équipe assignés au type d'événement seront utilisés.",
"hide_calendar_event_details": "Masquer les détails des événements du calendrier sur les calendriers partagés",
"description_hide_calendar_event_details": "Lorsqu'un calendrier est partagé, les événements sont visibles pour les lecteurs, mais leurs détails sont cachés pour ceux qui n'ont pas d'accès en écriture.",
"last_number_of_days": "{{count}} derniers jours",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "העתקת קישור פרטי",
"copy_private_link_to_event": "העתקת קישור פרטי לאירוע",
"private_link_description": "ניתן ליצור כתובת קישור פרטית מבלי לחשוף את המשתמש שלך- {{appName}}",
"multiple_private_links_title": "קישורים פרטיים",
"multiple_private_links_description": "צור כתובות URL פרטיות מבלי לחשוף את שם המשתמש, אשר יושמדו לאחר השימוש",
"add_a_multiple_private_link": "הוסף קישור חדש",
"multiple_private_link_copied": "הקישור הפרטי הועתק",
"invitees_can_schedule": "המוזמנים יכולים לקבוע מועד",
"date_range": "טווח תאריכים",
"calendar_days": "ימים קלנדריים",
"business_days": "ימי עסקים",
"set_address_place": "הגדר כתובת או מקום",
"set_link_meeting": "הגדר קישור לפגישה",
"managed_event_field_parent_control_disabled": "לא ניתן להפעיל. ניתן לפתוח רק עבור סוגי אירועים משניים",
"cal_invitee_phone_number_scheduling": "{{appName}} יציג לנמען בקשה להזנת מספר טלפון לפני קביעת ביצוע התזמון.",
"cal_provide_google_meet_location": "{{appName}} יספק מיקום Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} יספק קישור לפגישת Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "לשלוח למשתתף/ת תזכורת בדוא\"ל שעה אחת לפני תחילת האירועים",
"workflow_example_5": "לשלוח דוא\"ל מותאם אישית למארח/ת כאשר המועד של אירוע משתנה",
"workflow_example_6": "לשלוח הודעת SMS מותאמת אישית למארח/ת כאשר אירוע חדש מוזמן",
"count_managed_to_limit": "כלול ספירת הזמנות מסוגי אירועים מנוהלים",
"welcome_to_cal_header": "ברוך הבא אל {{appName}}!",
"edit_form_later_subtitle": "ניתן יהיה לערוך את זה מאוחר יותר.",
"connect_calendar_later": "אקשר את לוח השנה שלי מאוחר יותר",
@@ -2043,7 +2049,8 @@
"error_charging_card": "משהו השתבש בעת גביית דמי אי-הגעה. אפשר לנסות שוב מאוחר יותר.",
"collect_no_show_fee": "גביית דמי אי-הגעה",
"no_show_fee_charged": "דמי אי-הגעה חויבו",
"insights": "Insights",
"insights": "תובנות",
"routing_forms": "טפסי ניתוב",
"testing_workflow_info_message": "במהלך בדיקת תהליך העבודה הזה, קח/י בחשבון שניתן לתזמן הודעות דוא\"ל ו-SMS לפחות שעה אחת מראש",
"insights_no_data_found_for_filter": "לא נמצאו נתונים עבור המסנן שנבחר או התאריכים שנבחרו.",
"acknowledge_booking_no_show_fee": "מובן לי שאם לא אשתתף באירוע הזה, דמי אי-הגעה בסך {{amount, currency}} ינוכו מהכרטיס שלי.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "הגדרת הארגון שלך",
"set_up_your_platform_organization": "הגדרת הפלטפורמה שלך",
"organizations_description": "ארגונים הם סביבות משותפות שבהן צוותים יכולים ליצור משאבים משותפים, כמו סוגי אירועים, אפליקציות, תהליכי עבודה ועוד.",
"platform": "פלטפורמה",
"platform_description": "נהל את כל מה שקשור לפלטפורמה.",
"platform_organization_description": "פלטפורמת Cal.com מאפשרת לך לשלב תזמון בקלות באפליקציה שלך באמצעות APIs ו-atoms של הפלטפורמה.",
"must_enter_organization_name": "יש להזין שם ארגון",
"must_enter_organization_admin_email": "יש להזין את כתובת הדוא״ל של הארגון",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "ניתן להוסיף כרטיס אשראי אחד כדי לשלם על כל המינויים של הצוות שלך",
"advanced_managed_events": "סוגי אירועים מנוהלים מתקדמים",
"advanced_managed_events_description": "אפשר להוסיף כרטיס אשראי יחיד כדי לשלם עבור כל המינויים של הצוות שלך",
"enterprise": "ארגון",
"enterprise_description": "יש לשדרג לרישיון תאגידי כדי ליצור את הארגון שלך",
"create_your_org": "יצירת הארגון שלך",
"create_your_org_description": "אפשר לשדרג לרישיון תאגידי ולקבל תת־תחום, חיוב מאוחד, תובנות, שינוי מיתוג נרחב ועוד",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "השבת קלט אם מזהה ה-URL מולא מראש",
"booking_limits": "מגבלות הזמנה",
"booking_limits_team_description": "מגבלות הזמנה לחברי צוות בכל סוגי האירועים של הצוות",
"limit_team_booking_frequency_description": "הגבל כמה פעמים ניתן להזמין חברי צוות בכל סוגי האירועים של הצוות (קולקטיבי ו-round robin)",
"limit_team_booking_frequency_description": "הגבל את מספר הפעמים שניתן להזמין חברים בכל סוגי האירועים של הצוות",
"booking_limits_updated_successfully": "מגבלות ההזמנה עודכנו בהצלחה",
"you_are_unauthorized_to_make_this_change_to_the_booking": "אין לך הרשאה לבצע שינוי זה בהזמנה",
"matching_members": "חברים תואמים",
"no_matching_members": "אין חברים תואמים. המערכת תשתמש בחברי הצוות שהוקצו לסוג האירוע.",
"hide_calendar_event_details": "הסתר פרטי אירועי לוח שנה בלוחות שנה משותפים",
"description_hide_calendar_event_details": "כאשר לוח שנה משותף, האירועים נראים לקוראים אך פרטיהם מוסתרים מאלו שאין להם גישת כתיבה.",
"last_number_of_days": "ב{{count}} הימים האחרונים",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Privát link másolása",
"copy_private_link_to_event": "Privát link másolása az eseményhez",
"private_link_description": "Hozzon létre egy privát URL-t, amelyet megoszthat anélkül, hogy felfedné {{appName}} felhasználónevét",
"multiple_private_links_title": "Privát linkek",
"multiple_private_links_description": "Privát URL-ek generálása a felhasználónév felfedése nélkül, amelyek használat után megsemmisülnek",
"add_a_multiple_private_link": "Új link hozzáadása",
"multiple_private_link_copied": "Privát link másolva",
"invitees_can_schedule": "A meghívottak ütemezhetnek",
"date_range": "Időintervallum",
"calendar_days": "naptári napok",
"business_days": "munkanapok",
"set_address_place": "Állítson be egy címet vagy helyet",
"set_link_meeting": "Állítson be egy hivatkozást az értekezlethez",
"managed_event_field_parent_control_disabled": "Nem kapcsolható át. Csak a gyerek eseménytípusok számára oldható fel",
"cal_invitee_phone_number_scheduling": "{{appName}} megkéri a meghívottat, hogy adjon meg egy telefonszámot az ütemezés előtt.",
"cal_provide_google_meet_location": "{{appName}} biztosít egy Google Meet-helyszínt.",
"cal_provide_zoom_meeting_url": "{{appName}} megadja a Zoom megbeszélés URL-jét.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Emlékeztető küldése e-mailben 1 órával az események kezdete előtt a résztvevők számára",
"workflow_example_5": "Egyéni e-mail küldése, ha az eseményt átütemezték a házigazdának",
"workflow_example_6": "Egyéni SMS küldése, ha új eseményt lefoglaltak a házigazdának",
"count_managed_to_limit": "Tartalmazza a foglalási számokat a kezelt eseménytípusokból",
"welcome_to_cal_header": "Üdvözli a {{appName}}!",
"edit_form_later_subtitle": "Ezt később szerkesztheti.",
"connect_calendar_later": "Később csatlakoztatom a naptárat",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Szedje be a meg nem jelenési díjat",
"no_show_fee_charged": "Meg nem jelenés díja levonva",
"insights": "Betekintés",
"routing_forms": "Irányító űrlapok",
"testing_workflow_info_message": "A munkafolyamat tesztelésekor ügyeljen arra, hogy az e-mailek és SMS-ek legalább 1 órával későbbre ütemezhetők",
"insights_no_data_found_for_filter": "Nem található adat a kiválasztott szűrőhöz vagy a kiválasztott dátumokhoz.",
"acknowledge_booking_no_show_fee": "Tudomásul veszem, hogy ha nem veszek részt ezen az eseményen, {{amount, currency}} meg nem jelenési díj kerül felszámításra.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Állítsa be szervezetét",
"set_up_your_platform_organization": "Állítsa be a platformot",
"organizations_description": "A szervezetek megosztott környezetek, ahol a csapatok megosztott eseménytípusokat, alkalmazásokat, munkafolyamatokat és egyebeket hozhatnak létre.",
"platform": "Platform",
"platform_description": "Kezelje a platformmal kapcsolatos összes tevékenységet.",
"platform_organization_description": "A Cal.com Platform segítségével könnyedén integrálhatja az ütemezést az alkalmazásba a platform apis és atomok segítségével.",
"must_enter_organization_name": "Meg kell adni a szervezet nevét",
"must_enter_organization_admin_email": "Meg kell adnia a szervezet e-mail címét",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Adjon hozzá egyetlen hitelkártyát, hogy kifizesse csapata összes előfizetését",
"advanced_managed_events": "Speciális felügyelt eseménytípusok",
"advanced_managed_events_description": "Adjon hozzá egyetlen hitelkártyát, hogy kifizesse csapata összes előfizetését",
"enterprise": "Vállalat",
"enterprise_description": "Szervezete létrehozásához frissítsen Vállalati-ra",
"create_your_org": "Hozd létre a szervezetedet",
"create_your_org_description": "Frissítsen Vállalati-ra, és kapjon aldomaint, egységes számlázást, Elemzés szolgáltatást, kiterjedt fehér címkézést és sok mást",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Bemenet letiltása, ha az URL azonosító előre kitöltött",
"booking_limits": "Foglalási korlátok",
"booking_limits_team_description": "Foglalási korlátok a csapattagok számára az összes csapat eseménytípusra vonatkozóan",
"limit_team_booking_frequency_description": "Korlátozza, hogy a tagok hányszor foglalhatók az összes csapat eseménytípusra (kollektív és round-robin)",
"limit_team_booking_frequency_description": "Korlátozza, hogy a tagok hányszor foglalhatók le az összes csapat eseménytípuson belül",
"booking_limits_updated_successfully": "A foglalási korlátok sikeresen frissítve",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Nincs jogosultsága a foglalás módosításához",
"matching_members": "Megfelelő tagok",
"no_matching_members": "Nincsenek megfelelő tagok. Az eseménytípushoz rendelt csapattagok kerülnek felhasználásra.",
"hide_calendar_event_details": "Naptáresemény részleteinek elrejtése megosztott naptárakon",
"description_hide_calendar_event_details": "Amikor egy naptár meg van osztva, az események láthatóak az olvasók számára, de a részletek rejtve maradnak azok elől, akiknek nincs írási hozzáférésük.",
"last_number_of_days": "az elmúlt {{count}} nap",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copia link privato",
"copy_private_link_to_event": "Copia link privato nell'evento",
"private_link_description": "Genera un URL privato da condividere senza mostrare il tuo nome utente {{appName}}",
"multiple_private_links_title": "Link Privati",
"multiple_private_links_description": "Genera URL privati senza esporre il nome utente, che verranno distrutti una volta utilizzati",
"add_a_multiple_private_link": "Aggiungi nuovo link",
"multiple_private_link_copied": "Link privato copiato",
"invitees_can_schedule": "Gli inviti possono programmare",
"date_range": "Range di date",
"calendar_days": "giorni del calendario",
"business_days": "giorni lavorativi",
"set_address_place": "Imposta un indirizzo o un luogo",
"set_link_meeting": "Imposta un collegamento alla riunione",
"managed_event_field_parent_control_disabled": "Non può essere attivato. Può essere sbloccato solo per i tipi di eventi figli",
"cal_invitee_phone_number_scheduling": "{{appName}} chiederà al tuo invitato di inserire un numero di telefono prima della pianificazione.",
"cal_provide_google_meet_location": "{{appName}} fornirà un Google Meet location.",
"cal_provide_zoom_meeting_url": "{{appName}} fornirà un URL di riunione Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Invia al partecipante un promemoria via e-mail un'ora prima dell'inizio dell'evento",
"workflow_example_5": "Invia all'organizzatore un'e-mail personalizzata se l'evento viene riprogrammato",
"workflow_example_6": "Invia all'organizzatore un SMS personalizzato quando viene prenotato un nuovo evento",
"count_managed_to_limit": "Includi i conteggi delle prenotazioni dai tipi di eventi gestiti",
"welcome_to_cal_header": "Benvenuto in {{appName}}!",
"edit_form_later_subtitle": "Potrai fare delle modifiche in un secondo tempo.",
"connect_calendar_later": "Connetterò il mio calendario più tardi",
@@ -2043,7 +2049,8 @@
"error_charging_card": "L'addebito della penale per mancata presentazione non è andato a buon fine. Riprovare più tardi.",
"collect_no_show_fee": "Riscuoti penale per mancata presentazione",
"no_show_fee_charged": "Penale per mancata presentazione addebitata",
"insights": "Insights",
"insights": "Approfondimenti",
"routing_forms": "Moduli di Routing",
"testing_workflow_info_message": "Durante il test di questo flusso di lavoro, tieni presente che le e-mail e i messaggi SMS devono essere programmati con almeno 1 ora di anticipo",
"insights_no_data_found_for_filter": "Nessun dato trovato per il filtro selezionato o le date selezionate.",
"acknowledge_booking_no_show_fee": "Confermo che in caso di mia mancata partecipazione a questo evento, una penale per mancata presentazione di {{amount, currency}} verrà addebitata sulla mia carta.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Imposta la tua organizzazione",
"set_up_your_platform_organization": "Configura la tua piattaforma",
"organizations_description": "Le organizzazioni sono ambienti condivisi dove i team possono creare e condividere tipi di eventi, applicazioni, flussi di lavoro e altro ancora.",
"platform": "Piattaforma",
"platform_description": "Gestisci tutto ciò che riguarda la piattaforma.",
"platform_organization_description": "La piattaforma Cal.com ti permette di integrare facilmente la pianificazione nella tua app utilizzando API e atom della piattaforma.",
"must_enter_organization_name": "È necessario inserire il nome dell'organizzazione",
"must_enter_organization_admin_email": "È necessario inserire l'indirizzo e-mail dell'organizzazione",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Indica una singola carta di credito per pagare tutti gli abbonamenti del tuo team",
"advanced_managed_events": "Tipi di evento gestiti avanzati",
"advanced_managed_events_description": "Indica una singola carta di credito per pagare tutti gli abbonamenti del tuo team",
"enterprise": "Impresa",
"enterprise_description": "Passa a Enterprise per creare la tua organizzazione",
"create_your_org": "Crea la tua organizzazione",
"create_your_org_description": "Passa a Organizations per avere sottodominio, fatturazione unificata, approfondimenti, personalizzazione completa e altro ancora",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Disabilita input se l'identificatore URL è precompilato",
"booking_limits": "Limiti di Prenotazione",
"booking_limits_team_description": "Limiti di prenotazione per i membri del team in tutti i tipi di eventi del team",
"limit_team_booking_frequency_description": "Limita quante volte i membri possono essere prenotati in tutti i tipi di eventi del team (collettivi e round-robin)",
"limit_team_booking_frequency_description": "Limita quante volte i membri possono essere prenotati su tutti i tipi di eventi del team",
"booking_limits_updated_successfully": "Limiti di prenotazione aggiornati con successo",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Non sei autorizzato a effettuare questa modifica alla prenotazione",
"matching_members": "Membri corrispondenti",
"no_matching_members": "Nessun membro corrispondente. Verrà utilizzato il fallback con i membri del team assegnati al tipo di evento.",
"hide_calendar_event_details": "Nascondi i dettagli degli eventi del calendario nei calendari condivisi",
"description_hide_calendar_event_details": "Quando un calendario è condiviso, gli eventi sono visibili ai lettori ma i loro dettagli sono nascosti a chi non ha accesso in scrittura.",
"last_number_of_days": "ultimi {{count}} giorni",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "プライベートリンクをコピー",
"copy_private_link_to_event": "イベントのプライベートリンクをコピー",
"private_link_description": "{{appName}} ユーザー名を公開せずに共有するプライベートURLを生成",
"multiple_private_links_title": "プライベートリンク",
"multiple_private_links_description": "ユーザー名を公開せずにプライベートURLを生成し、一度使用されると破棄されます",
"add_a_multiple_private_link": "新しいリンクを追加",
"multiple_private_link_copied": "プライベートリンクがコピーされました",
"invitees_can_schedule": "招待されるメンバーはスケジュールできる",
"date_range": "日付の範囲",
"calendar_days": "暦日",
"business_days": "営業日",
"set_address_place": "住所または場所を設定",
"set_link_meeting": "ミーティングのリンクを設定",
"managed_event_field_parent_control_disabled": "切り替えできません。子イベントタイプのためにのみ解除できます",
"cal_invitee_phone_number_scheduling": "招待されるメンバーは予約する前に {{appName}} によって電話番号の入力を求められる。",
"cal_provide_google_meet_location": "{{appName}} は GoogleMeet の場所を提供する。",
"cal_provide_zoom_meeting_url": "{{appName}} は Zoom ミーティングの URLを提供する。",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "イベントの開始 1 時間前に、出席者にメールで通知を送信する",
"workflow_example_5": "イベントスケジュールの変更時に、ホストにカスタムメールを送信する",
"workflow_example_6": "新しいイベントの予約時に、ホストにカスタム SMS を送信する",
"count_managed_to_limit": "管理されているイベントタイプの予約数を含める",
"welcome_to_cal_header": "{{appName}} へようこそ!",
"edit_form_later_subtitle": "これは後で編集することができます。",
"connect_calendar_later": "後でカレンダーを接続する",
@@ -2043,7 +2049,8 @@
"error_charging_card": "不参加費用の請求時にエラーが発生しました。後でもう一度お試しください。",
"collect_no_show_fee": "不参加費用を徴収する",
"no_show_fee_charged": "不参加費用が請求されました",
"insights": "Insights",
"insights": "インサイト",
"routing_forms": "ルーティングフォーム",
"testing_workflow_info_message": "このワークフローをテストする場合、少なくとも 1 時間前でなければメールと SMS のスケジュール設定ができないことにご注意ください",
"insights_no_data_found_for_filter": "選択したフィルターまたは日付のデータが見つかりませんでした。",
"acknowledge_booking_no_show_fee": "このイベントに出席しなかった場合、不参加費用として {{amount, currency}} が私のカードに請求されることに同意します。",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "組織をセットアップする",
"set_up_your_platform_organization": "プラットフォームを設定する",
"organizations_description": "組織は、チームが共有するイベントの種類、アプリ、ワークフローなどが作成可能な共有環境です。",
"platform": "プラットフォーム",
"platform_description": "プラットフォームに関連するすべてを管理します。",
"platform_organization_description": "Cal.comプラットフォームを使用すると、プラットフォームAPIとアトムを使用してスケジューリングをアプリに簡単に統合できます。",
"must_enter_organization_name": "組織名は必須項目です",
"must_enter_organization_admin_email": "組織のメールアドレスは必須項目です",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "チーム全体のサブスクリプションを支払うためのクレジットカードを1枚追加する",
"advanced_managed_events": "高度な管理イベントタイプ",
"advanced_managed_events_description": "チーム全体のサブスクリプションを支払うためのクレジットカードを1枚追加する",
"enterprise": "エンタープライズ",
"enterprise_description": "エンタープライズにアップグレードして組織を作成する",
"create_your_org": "組織を作成する",
"create_your_org_description": "組織にアップグレードして、サブドメイン、統一請求、インサイト、広範なホワイトラベリングなどを受け取る",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "URL識別子が事前入力されている場合は入力を無効にする",
"booking_limits": "予約制限",
"booking_limits_team_description": "チームメンバーの全てのチームイベントタイプに対する予約制限",
"limit_team_booking_frequency_description": "チームメンバーが全てのチームイベントタイプ(集団およびround-robin)で予約される回数を制限",
"limit_team_booking_frequency_description": "チームのすべてのイベントタイプにおいて、メンバーが予約される回数を制限する",
"booking_limits_updated_successfully": "予約制限が正常に更新されました",
"you_are_unauthorized_to_make_this_change_to_the_booking": "この予約の変更を行う権限がありません",
"matching_members": "一致するメンバー",
"no_matching_members": "一致するメンバーがいません。イベントタイプに割り当てられたチームメンバーが使用されます。",
"hide_calendar_event_details": "共有カレンダーのイベント詳細を非表示にする",
"description_hide_calendar_event_details": "カレンダーが共有されると、イベントは閲覧者に表示されますが、書き込み権限のない人には詳細が非表示になります。",
"last_number_of_days": "過去{{count}}日間",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "ចម្លងតំណផ្ទាល់ខ្លួន",
"copy_private_link_to_event": "ចម្លងតំណផ្ទាល់ខ្លួនទៅព្រឹត្តិការណ៍",
"private_link_description": "បង្កើត URL ផ្ទាល់ខ្លួនដើម្បីចែករំលែកដោយមិនបង្ហាញឈ្មោះអ្នកប្រើ {{appName}} របស់អ្នក",
"multiple_private_links_title": "តំណភ្ជាប់ឯកជន",
"multiple_private_links_description": "បង្កើត URL ឯកជនដោយមិនបង្ហាញឈ្មោះអ្នកប្រើ ហើយវានឹងត្រូវបានបំផ្លាញបន្ទាប់ពីប្រើប្រាស់",
"add_a_multiple_private_link": "បន្ថែមតំណភ្ជាប់ថ្មី",
"multiple_private_link_copied": "បានចម្លងតំណភ្ជាប់ឯកជន",
"invitees_can_schedule": "ភ្ញៀវអាចកំណត់ពេលវេលា",
"date_range": "ជួរថ្ងៃទី",
"calendar_days": "ថ្ងៃប្រតិទិន",
"business_days": "ថ្ងៃធ្វើការ",
"set_address_place": "កំណត់អាសយដ្ឋាន ឬទីកន្លែង",
"set_link_meeting": "កំណត់តំណទៅកិច្ចប្រជុំ",
"managed_event_field_parent_control_disabled": "មិនអាចបើកបិទបានទេ។ វាអាចត្រូវបានដោះសោរតែសម្រាប់ប្រភេទព្រឹត្តិការណ៍កូនប៉ុណ្ណោះ",
"cal_invitee_phone_number_scheduling": "{{appName}} នឹងស្នើឱ្យភ្ញៀវរបស់អ្នកបញ្ចូលលេខទូរស័ព្ទមុនពេលកំណត់ពេលវេលា។",
"cal_provide_google_meet_location": "{{appName}} នឹងផ្តល់ទីតាំង Google Meet។",
"cal_provide_zoom_meeting_url": "{{appName}} នឹងផ្តល់ URL កិច្ចប្រជុំ Zoom។",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "ផ្ញើការរំលឹកតាមអ៊ីមែល 1 ម៉ោងមុនព្រឹត្តិការណ៍ចាប់ផ្តើមទៅអ្នកចូលរួម",
"workflow_example_5": "ផ្ញើអ៊ីមែលផ្ទាល់ខ្លួននៅពេលព្រឹត្តិការណ៍ត្រូវបានកែប្រែទៅម្ចាស់ផ្ទះ",
"workflow_example_6": "ផ្ញើសារតាមសារ SMS ផ្ទាល់ខ្លួននៅពេលមានព្រឹត្តិការណ៍ថ្មីត្រូវបានកក់ទៅម្ចាស់ផ្ទះ",
"count_managed_to_limit": "រួមបញ្ចូលចំនួនការកក់ពីប្រភេទព្រឹត្តិការណ៍ដែលគ្រប់គ្រង",
"welcome_to_cal_header": "សូមស្វាគមន៍មកកាន់ {{appName}}!",
"edit_form_later_subtitle": "អ្នកអាចកែសម្រួលវាបាននៅពេលក្រោយ។",
"connect_calendar_later": "ខ្ញុំនឹងភ្ជាប់ប្រតិទិនរបស់ខ្ញុំនៅពេលក្រោយ",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "ប្រមូលថ្លៃសេវាកម្មមិនមកចូលរួម",
"no_show_fee_charged": "បានគិតថ្លៃសេវាកម្មមិនមកចូលរួម",
"insights": "ព័ត៌មានជ្រៅ",
"routing_forms": "បែបបទបញ្ជូន",
"testing_workflow_info_message": "នៅពេលសាកល្បងដំណើរការនេះ សូមចំណាំថា អ៊ីមែល និងសារ SMS អាចត្រូវបានកំណត់ពេលយ៉ាងហោចណាស់ 1 ម៉ោងមុន",
"insights_no_data_found_for_filter": "មិនមានទិន្នន័យសម្រាប់តម្រង ឬកាលបរិច្ឆេទដែលបានជ្រើស។",
"acknowledge_booking_no_show_fee": "ខ្ញុំយល់ព្រមថា ប្រសិនបើខ្ញុំមិនចូលរួមព្រឹត្តិការណ៍នេះ នោះថ្លៃសេវាកម្មមិនមកចូលរួមចំនួន {{amount, currency}} នឹងត្រូវបានគិតលើកាតរបស់ខ្ញុំ។",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "រៀបចំអង្គការរបស់អ្នក",
"set_up_your_platform_organization": "រៀបចំវេទិការបស់អ្នក",
"organizations_description": "អង្គការគឺជាបរិយាកាសចែករំលែកដែលក្រុមអាចបង្កើតប្រភេទព្រឹត្តិការណ៍ចែករំលែក កម្មវិធី ដំណើរការ និងច្រើនទៀត។",
"platform": "វេទិកា",
"platform_description": "គ្រប់គ្រងអ្វីៗទាំងអស់ដែលទាក់ទងនឹងវេទិកា។",
"platform_organization_description": "វេទិកា Cal.com អនុញ្ញាតឱ្យអ្នករួមបញ្ចូលការកំណត់ពេលវេលាដោយគ្មានការលំបាកទៅក្នុងកម្មវិធីរបស់អ្នកដោយប្រើ apis និង atoms វេទិកា។",
"must_enter_organization_name": "ត្រូវបញ្ចូលឈ្មោះអង្គការ",
"must_enter_organization_admin_email": "ត្រូវបញ្ចូលអាសយដ្ឋានអ៊ីមែលរបស់អង្គការរបស់អ្នក",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "បន្ថែមកាតឥណទានតែមួយដើម្បីបង់ប្រាក់សម្រាប់ការជាវទាំងអស់របស់ក្រុមអ្នក",
"advanced_managed_events": "ប្រភេទព្រឹត្តិការណ៍ដែលគ្រប់គ្រងកម្រិតខ្ពស់",
"advanced_managed_events_description": "បន្ថែមកាតឥណទានតែមួយដើម្បីបង់ប្រាក់សម្រាប់ការជាវទាំងអស់របស់ក្រុមអ្នក",
"enterprise": "សហគ្រាស",
"enterprise_description": "ធ្វើឱ្យប្រសើរឡើងទៅកម្រិត Enterprise ដើម្បីបង្កើតអង្គការរបស់អ្នក",
"create_your_org": "បង្កើតអង្គការរបស់អ្នក",
"create_your_org_description": "ធ្វើឱ្យប្រសើរឡើងទៅកម្រិត Organizations និងទទួលបានអនុវត្តន៍រង, វិក្កយបត្រតែមួយ, Insights, ការប្រើប្រាស់ស្លាកសញ្ញាដ៏ទូលំទូលាយ និងផ្សេងៗទៀត",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "បិទការបញ្ចូលប្រសិនបើ URL identifier ត្រូវបានបំពេញរួចហើយ",
"booking_limits": "ដែនកំណត់ការកក់",
"booking_limits_team_description": "ដែនកំណត់ការកក់សម្រាប់សមាជិកក្រុមទាំងអស់ក្នុងប្រភេទព្រឹត្តិការណ៍ក្រុមទាំងអស់",
"limit_team_booking_frequency_description": "ដែនកំណត់ចំនួនដងដែលសមាជិកអាចត្រូវបានកក់ក្នុងប្រភេទព្រឹត្តិការណ៍ក្រុមទាំងអស់ (សហគមន៍ និង round-robin)",
"limit_team_booking_frequency_description": "កំណត់ចំនួនដងដែលសមាជិកអាចត្រូវបានកក់នៅក្នុងប្រភេទព្រឹត្តិការណ៍របស់ក្រុមទាំងអស់",
"booking_limits_updated_successfully": "ដែនកំណត់ការកក់ត្រូវបានធ្វើបច្ចុប្បន្នភាពដោយជោគជ័យ",
"you_are_unauthorized_to_make_this_change_to_the_booking": "អ្នកមិនមានសិទ្ធិធ្វើការផ្លាស់ប្តូរនេះលើការកក់ទេ",
"matching_members": "សមាជិកដែលត្រូវគ្នា",
"no_matching_members": "គ្មានសមាជិកដែលត្រូវគ្នា។ វានឹងត្រឡប់ទៅប្រើសមាជិកក្រុមដែលបានចាត់តាំងទៅប្រភេទព្រឹត្តិការណ៍។",
"hide_calendar_event_details": "លាក់ព័ត៌មានលម្អិតនៃព្រឹត្តិការណ៍ប្រចាំប្រតិទិននៅលើប្រតិទិនដែលបានចែករំលែក",
"description_hide_calendar_event_details": "នៅពេលដែលប្រតិទិនត្រូវបានចែករំលែក ព្រឹត្តិការណ៍នឹងមើលឃើញបានសម្រាប់អ្នកអាន ប៉ុន្តែព័ត៌មានលម្អិតនឹងត្រូវបានលាក់ពីអ្នកដែលមិនមានសិទ្ធិចូលសរសេរ។",
"last_number_of_days": "ចុងក្រោយ {{count}} ថ្ងៃ",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "비공개 링크 복사",
"copy_private_link_to_event": "이벤트의 비공개 링크 복사",
"private_link_description": "{{appName}} 사용자 이름을 노출하지 않고 공유할 비공개 URL 생성",
"multiple_private_links_title": "비공개 링크",
"multiple_private_links_description": "사용자 이름을 노출하지 않고 비공개 URL을 생성하며, 사용 후에는 삭제됩니다.",
"add_a_multiple_private_link": "새 링크 추가",
"multiple_private_link_copied": "비공개 링크가 복사되었습니다.",
"invitees_can_schedule": "초대받은 사람은 일정을 잡을 수 있습니다.",
"date_range": "날짜 범위",
"calendar_days": "일",
"business_days": "영업일",
"set_address_place": "주소 또는 장소 설정",
"set_link_meeting": "회의 링크 설정",
"managed_event_field_parent_control_disabled": "전환할 수 없습니다. 하위 이벤트 유형에 대해서만 잠금 해제할 수 있습니다.",
"cal_invitee_phone_number_scheduling": "{{appName}}은 일정을 잡기 전에 초대받은 사람에게 전화번호를 요청합니다.",
"cal_provide_google_meet_location": "{{appName}}은 Google Meet 위치를 제공합니다.",
"cal_provide_zoom_meeting_url": "{{appName}}은 Zoom 회의 URL을 제공합니다.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "이벤트가 시작되기 1시간 전에 참석자에게 이메일 알림 보내기",
"workflow_example_5": "이벤트 일정이 변경되면 호스트에게 사용자 정의 SMS 보내기",
"workflow_example_6": "호스트에 새 이벤트가 예약되면 사용자 정의 SMS 보내기",
"count_managed_to_limit": "관리되는 이벤트 유형의 예약 횟수 포함",
"welcome_to_cal_header": "{{appName}}오신 것을 환영합니다!",
"edit_form_later_subtitle": "이것은 나중에 수정할 수 있습니다.",
"connect_calendar_later": "내 캘린더를 나중에 연결하겠습니다",
@@ -2043,7 +2049,8 @@
"error_charging_card": "노쇼 수수료를 부과하는 중 문제가 발생했습니다. 나중에 다시 시도해주세요.",
"collect_no_show_fee": "노쇼 수수료 청구",
"no_show_fee_charged": "노쇼 수수료 부과됨",
"insights": "Insights",
"insights": "인사이트",
"routing_forms": "라우팅 양식",
"testing_workflow_info_message": "이 워크플로를 테스트할 때 이메일 및 SMS는 최소 1시간 전에만 예약할 수 있다는 점에 유의하세요",
"insights_no_data_found_for_filter": "선택한 필터 또는 날짜에 대한 데이터를 찾을 수 없습니다.",
"acknowledge_booking_no_show_fee": "본인은 이 이벤트에 참석하지 않을 경우 {{amount, currency}}에 대한 노쇼 수수료가 내 카드에 부과됨을 인정합니다.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "조직 설정",
"set_up_your_platform_organization": "플랫폼 설정",
"organizations_description": "조직은 팀이 공유 이벤트 유형, 앱, 워크플로 등을 만들 수 있는 공유 환경입니다.",
"platform": "플랫폼",
"platform_description": "플랫폼과 관련된 모든 것을 관리합니다.",
"platform_organization_description": "Cal.com 플랫폼을 사용하면 플랫폼 API와 아톰을 통해 손쉽게 앱에 스케줄링을 통합할 수 있습니다.",
"must_enter_organization_name": "조직 이름을 입력해야 합니다",
"must_enter_organization_admin_email": "조직 이메일 주소를 입력해야 합니다",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "모든 팀의 구독을 결제할 단일 신용카드를 추가하세요",
"advanced_managed_events": "고급 관리 이벤트 유형",
"advanced_managed_events_description": "모든 팀의 구독을 결제할 단일 신용카드를 추가하세요",
"enterprise": "엔터프라이즈",
"enterprise_description": "Enterprise로 업그레이드하여 조직을 만드세요",
"create_your_org": "조직 만들기",
"create_your_org_description": "Organizations로 업그레이드하고 서브도메인, 통합 결제, 인사이트, 광범위한 화이트라벨링 등을 받으세요",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "URL 식별자가 미리 채워진 경우 입력 비활성화",
"booking_limits": "예약 제한",
"booking_limits_team_description": "모든 팀 이벤트 유형에 대한 팀원들의 예약 제한",
"limit_team_booking_frequency_description": "모든 팀 이벤트 유형(집단 및 round-robin)에서 팀원들이 예약될 수 있는 횟수를 제한합니다",
"limit_team_booking_frequency_description": "모든 팀 이벤트 유형에서 멤버가 예약될 수 있는 횟수를 제한합니다.",
"booking_limits_updated_successfully": "예약 제한이 성공적으로 업데이트되었습니다",
"you_are_unauthorized_to_make_this_change_to_the_booking": "이 예약을 변경할 권한이 없습니다",
"matching_members": "일치하는 멤버",
"no_matching_members": "일치하는 멤버가 없습니다. 이벤트 유형에 할당된 팀 멤버를 사용할 것입니다.",
"hide_calendar_event_details": "공유 캘린더에서 이벤트 세부 정보 숨기기",
"description_hide_calendar_event_details": "캘린더가 공유되면 이벤트는 읽기 권한이 있는 사람에게 보이지만, 쓰기 권한이 없는 사람에게는 세부 정보가 숨겨집니다.",
"last_number_of_days": "지난 {{count}}일",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Privélink kopiëren",
"copy_private_link_to_event": "Kopieer privélink naar evenement",
"private_link_description": "Genereer een privé-URL om te delen zonder uw {{appName}}-gebruikersnaam te onthullen",
"multiple_private_links_title": "Privélinks",
"multiple_private_links_description": "Genereer privé-URL's zonder de gebruikersnaam bloot te stellen, die na gebruik worden vernietigd",
"add_a_multiple_private_link": "Nieuwe link toevoegen",
"multiple_private_link_copied": "Privélink gekopieerd",
"invitees_can_schedule": "Genodigden kunnen plannen",
"date_range": "Date Range",
"calendar_days": "kalender dagen",
"business_days": "werkdagen",
"set_address_place": "Een adres of plaats instellen",
"set_link_meeting": "Stel een link in naar de vergadering",
"managed_event_field_parent_control_disabled": "Kan niet worden in- of uitgeschakeld. Kan alleen worden ontgrendeld voor subgebeurtenistypen",
"cal_invitee_phone_number_scheduling": "{{appName}} zal de genodigde om een telefoonnummer vragen.",
"cal_provide_google_meet_location": "{{appName}} zal een Google Meet meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_zoom_meeting_url": "{{appName}} zal een Zoom meeting-URL meegeven in de afspraak bevestiging.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "1 uur voor het begin van gebeurtenissen een e-mailherinnering naar deelnemer versturen",
"workflow_example_5": "Aangepaste e-mail versturen naar organisator wanneer gebeurtenis wordt verplaatst",
"workflow_example_6": "Aangepaste sms versturen naar organisator wanneer een nieuwe gebeurtenis wordt geboekt",
"count_managed_to_limit": "Inclusief boekingsaantallen van beheerde evenementtypen",
"welcome_to_cal_header": "Welkom bij {{appName}}!",
"edit_form_later_subtitle": "U kunt dit later bewerken.",
"connect_calendar_later": "Ik koppel mijn agenda later",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Er is iets misgegaan met het in rekening brengen van de afwezigheidsvergoeding. Probeer het later opnieuw.",
"collect_no_show_fee": "Afwezigheidsvergoeding innen",
"no_show_fee_charged": "Afwezigheidsvergoeding in rekening gebracht",
"insights": "Insights",
"insights": "Inzichten",
"routing_forms": "Routeringsformulieren",
"testing_workflow_info_message": "Let er bij het testen van deze werkstroom op dat e-mails en sms minimaal 1 uur van tevoren kunnen gepland moeten worden",
"insights_no_data_found_for_filter": "Geen gegevens gevonden voor het geselecteerde filter of de geselecteerde datums.",
"acknowledge_booking_no_show_fee": "Ik erken dat als ik deze gebeurtenis niet bijwoon, er {{amount, currency}} aan afwezigheidsvergoeding van mijn kaart worden afgeschreven.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Stel uw organisatie in",
"set_up_your_platform_organization": "Stel je platform in",
"organizations_description": "Organisaties zijn gedeelde omgevingen waar teams gedeelde gebeurtenistypen, apps, werkstromen en meer kunnen maken.",
"platform": "Platform",
"platform_description": "Beheer alles wat met het platform te maken heeft.",
"platform_organization_description": "Cal.com Platform stelt je in staat om plannen moeiteloos te integreren in je app met behulp van platform-API's en -atomen.",
"must_enter_organization_name": "U moet een organisatienaam invoeren",
"must_enter_organization_admin_email": "U moet het e-mailadres van uw organisatie invoeren",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Voeg een enkele creditcard toe om voor alle abonnementen van je team te betalen",
"advanced_managed_events": "Geavanceerde beheerde evenementtypes",
"advanced_managed_events_description": "Voeg een enkele creditcard toe om voor alle abonnementen van je team te betalen",
"enterprise": "Onderneming",
"enterprise_description": "Upgrade naar Enterprise om je Organisatie te creëren",
"create_your_org": "Creëer je Organisatie",
"create_your_org_description": "Upgrade naar Organisaties en ontvang een subdomein, uniforme facturering, inzichten, uitgebreide whitelabeling en meer",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Invoer uitschakelen als de URL-identificatie vooraf is ingevuld",
"booking_limits": "Boekingslimieten",
"booking_limits_team_description": "Boekingslimieten voor teamleden voor alle soorten teamevenementen",
"limit_team_booking_frequency_description": "Beperk hoe vaak teamleden geboekt kunnen worden voor alle soorten teamevenementen (collectief en round-robin)",
"limit_team_booking_frequency_description": "Beperk hoe vaak leden kunnen worden geboekt voor alle team evenementtypen",
"booking_limits_updated_successfully": "Boekingslimieten succesvol bijgewerkt",
"you_are_unauthorized_to_make_this_change_to_the_booking": "U bent niet gemachtigd om deze wijziging in de boeking aan te brengen",
"matching_members": "Overeenkomende leden",
"no_matching_members": "Geen overeenkomende leden. Er wordt teruggevallen op de teamleden die aan het type evenement zijn toegewezen.",
"hide_calendar_event_details": "Verberg details van kalendergebeurtenissen op gedeelde kalenders",
"description_hide_calendar_event_details": "Wanneer een kalender wordt gedeeld, zijn gebeurtenissen zichtbaar voor lezers, maar hun details zijn verborgen voor degenen zonder schrijfrechten.",
"last_number_of_days": "laatste {{count}} dagen",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Kopier privat lenke",
"copy_private_link_to_event": "Kopier privat lenke til hendelse",
"private_link_description": "Generer en privat URL for å dele uten å avsløre {{appName}}-brukernavnet ditt",
"multiple_private_links_title": "Private lenker",
"multiple_private_links_description": "Generer private URL-er uten å avsløre brukernavnet, som vil bli ødelagt etter bruk",
"add_a_multiple_private_link": "Legg til ny lenke",
"multiple_private_link_copied": "Privat lenke kopiert",
"invitees_can_schedule": "Inviterte kan velge tidspunkt",
"date_range": "Datointervall",
"calendar_days": "kalenderdager",
"business_days": "virkedager",
"set_address_place": "Angi en adresse eller sted",
"set_link_meeting": "Angi en lenke til møtet",
"managed_event_field_parent_control_disabled": "Kan ikke slås av/på. Kan kun låses opp for underordnede hendelsestyper",
"cal_invitee_phone_number_scheduling": "{{appName}} vil be den inviterte om å skrive inn et telefonnummer før valg av tidspunkt.",
"cal_provide_google_meet_location": "{{appName}} vil oppgi en Google Meet-lokasjon.",
"cal_provide_zoom_meeting_url": "{{appName}} vil angi en URL-adresse for Zoom-møte.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Send deltakeren en e-post-påminnelse 1 time før hendelser starter",
"workflow_example_5": "Send verten en tilpasset e-post når en hendelse får nytt tidspunkt",
"workflow_example_6": "Send verten en tilpasset SMS når en ny hendelse er booket",
"count_managed_to_limit": "Inkluder antall bookinger fra administrerte hendelsestyper",
"welcome_to_cal_header": "Velkommen til {{appName}}!",
"edit_form_later_subtitle": "Du kan redigere dette senere.",
"connect_calendar_later": "Jeg kobler til kalenderen min senere",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Innkrev gebyr for manglende oppmøte",
"no_show_fee_charged": "Gebyr for manglende oppmøte belastet",
"insights": "Innsikt",
"routing_forms": "Rute skjemaer",
"testing_workflow_info_message": "Når du tester denne arbeidsflyten, vær oppmerksom på at e-poster og SMS kun kan planlegges minst 1 time i forveien",
"insights_no_data_found_for_filter": "Ingen data funnet for det valgte filteret eller de valgte datoene.",
"acknowledge_booking_no_show_fee": "Jeg erkjenner at hvis jeg ikke deltar på dette arrangementet, vil et gebyr på {{amount, currency}} for manglende oppmøte bli belastet kortet mitt.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Sett opp din organisasjon",
"set_up_your_platform_organization": "Sett opp din plattform",
"organizations_description": "Organisasjoner er delte miljøer hvor team kan lage delte hendelsestyper, apper, arbeidsflyter og mer.",
"platform": "Plattform",
"platform_description": "Administrer alt relatert til plattformen.",
"platform_organization_description": "Cal.com Platform lar deg integrere planlegging sømløst i appen din ved hjelp av plattform-APIer og atomer.",
"must_enter_organization_name": "Du må oppgi et organisasjonsnavn",
"must_enter_organization_admin_email": "Du må oppgi din organisasjons e-postadresse",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Legg til et enkelt kredittkort for å betale for alle teamets abonnementer",
"advanced_managed_events": "Avanserte Administrerte Hendelsestyper",
"advanced_managed_events_description": "Legg til et enkelt kredittkort for å betale for alle teamets abonnementer",
"enterprise": "Bedrift",
"enterprise_description": "Oppgrader til Enterprise for å opprette din organisasjon",
"create_your_org": "Opprett din Organisasjon",
"create_your_org_description": "Oppgrader til Organisasjoner og få et underdomene, enhetlig fakturering, innsikt, omfattende whitelabeling og mer",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Deaktiver inndata hvis URL-identifikatoren er forhåndsutfylt",
"booking_limits": "Bestillingsgrenser",
"booking_limits_team_description": "Bestillingsgrenser for teammedlemmer på tvers av alle teamhendelsestyper",
"limit_team_booking_frequency_description": "Begrens hvor mange ganger medlemmer kan bookes på tvers av alle teamhendelsestyper (kollektivt og round-robin)",
"limit_team_booking_frequency_description": "Begrens hvor mange ganger medlemmer kan bookes på tvers av alle teamhendelsestyper",
"booking_limits_updated_successfully": "Bestillingsgrenser oppdatert vellykket",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Du har ikke tillatelse til å gjøre denne endringen i bestillingen",
"matching_members": "Matchende medlemmer",
"no_matching_members": "Ingen matchende medlemmer. Det vil falle tilbake til å bruke teammedlemmene som er tildelt hendelsestypen.",
"hide_calendar_event_details": "Skjul kalenderhendelsesdetaljer på delte kalendere",
"description_hide_calendar_event_details": "Når en kalender deles, er hendelser synlige for lesere, men detaljene er skjult for de uten skriveadgang.",
"last_number_of_days": "siste {{count}} dager",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Skopiuj link prywatny",
"copy_private_link_to_event": "Skopiuj prywatny link do wydarzenia",
"private_link_description": "Wygeneruj prywatny adres URL do udostępniania bez ujawniania Twojej nazwy użytkownika {{appName}}",
"multiple_private_links_title": "Prywatne Linki",
"multiple_private_links_description": "Generuj prywatne adresy URL bez ujawniania nazwy użytkownika, które zostaną zniszczone po użyciu",
"add_a_multiple_private_link": "Dodaj nowy link",
"multiple_private_link_copied": "Prywatny link skopiowany",
"invitees_can_schedule": "Zaproszeni mogą planować",
"date_range": "Zakres czasu",
"calendar_days": "dni kalendarzowe",
"business_days": "dni robocze",
"set_address_place": "Ustaw adres lub miejsce",
"set_link_meeting": "Ustaw link do spotkania",
"managed_event_field_parent_control_disabled": "Nie można przełączyć. Może być odblokowane tylko dla typów wydarzeń podrzędnych",
"cal_invitee_phone_number_scheduling": "{{appName}} poprosi swojego zaproszonego o wprowadzenie numeru telefonu przed planowaniem.",
"cal_provide_google_meet_location": "{{appName}} zapewni lokalizację Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} zapewni URL spotkania Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Wyślij do uczestnika wiadomość e-mail z przypomnieniem na 1 godzinę przed rozpoczęciem wydarzenia",
"workflow_example_5": "Wyślij do gospodarza niestandardową wiadomość e-mail, gdy wydarzenie zostanie przełożone",
"workflow_example_6": "Wyślij do gospodarza niestandardową wiadomość SMS, gdy zostanie zarezerwowane nowe wydarzenie",
"count_managed_to_limit": "Uwzględnij liczbę rezerwacji z zarządzanych typów wydarzeń",
"welcome_to_cal_header": "Witaj w {{appName}}!",
"edit_form_later_subtitle": "Będzie można edytować to później.",
"connect_calendar_later": "Połączę mój kalendarz później",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Coś poszło nie tak podczas pobierania opłaty za niestawienie się. Spróbuj ponownie później.",
"collect_no_show_fee": "Pobierz opłatę za niestawienie się",
"no_show_fee_charged": "Pobrano opłatę za niestawienie się",
"insights": "Insights",
"insights": "Wglądy",
"routing_forms": "Formularze routingu",
"testing_workflow_info_message": "Podczas testowania tego przepływu pracy pamiętaj, że wiadomości e-mail i SMS można zaplanować jedynie z co najmniej 1-godzinnym wyprzedzeniem",
"insights_no_data_found_for_filter": "Nie znaleziono danych dotyczących wybranego filtru lub wskazanych dat.",
"acknowledge_booking_no_show_fee": "Rozumiem, że jeśli nie wezmę udziału w wydarzeniu, z mojej karty pobrana zostanie opłata za niestawienie się w wysokości {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Skonfiguruj swoją organizację",
"set_up_your_platform_organization": "Skonfiguruj swoją platformę",
"organizations_description": "Organizacje to współdzielone środowiska, w których zespoły mogą tworzyć wspólne typy wydarzeń, aplikacje, przepływy pracy itd.",
"platform": "Platforma",
"platform_description": "Zarządzaj wszystkim, co związane z platformą.",
"platform_organization_description": "Platforma Cal.com pozwala na bezproblemową integrację harmonogramowania z Twoją aplikacją za pomocą API i atomów platformy.",
"must_enter_organization_name": "Należy wprowadzić nazwę organizacji",
"must_enter_organization_admin_email": "Należy wprowadzić adres e-mail swojej organizacji",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Dodaj jedną kartę kredytową, aby opłacać wszystkie subskrypcje swojego zespołu",
"advanced_managed_events": "Zaawansowane zarządzane typy wydarzeń",
"advanced_managed_events_description": "Dodaj jedną kartę kredytową, aby opłacić wszystkie subskrypcje swojego zespołu",
"enterprise": "Przedsiębiorstwo",
"enterprise_description": "Ulepsz do wersji Enterprise, aby utworzyć swoją Organizację",
"create_your_org": "Utwórz swoją Organizację",
"create_your_org_description": "Ulepsz do wersji Organizations i otrzymaj subdomenę, zintegrowane rozliczenia, Insights, rozbudowane możliwości whitelabelingu i więcej",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Wyłącz wprowadzanie, jeśli identyfikator URL jest wypełniony",
"booking_limits": "Limity rezerwacji",
"booking_limits_team_description": "Limity rezerwacji dla członków zespołu we wszystkich typach wydarzeń zespołowych",
"limit_team_booking_frequency_description": "Ogranicz, ile razy członkowie mogą być rezerwowani we wszystkich typach wydarzeń zespołowych (zbiorowe i round-robin)",
"limit_team_booking_frequency_description": "Ogranicz, ile razy członkowie mogą być rezerwowani we wszystkich typach wydarzeń zespołu",
"booking_limits_updated_successfully": "Limity rezerwacji zostały pomyślnie zaktualizowane",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Nie masz uprawnień do wprowadzenia tej zmiany w rezerwacji",
"matching_members": "Pasujący członkowie",
"no_matching_members": "Brak pasujących członków. Zostaną użyci członkowie zespołu przypisani do typu wydarzenia.",
"hide_calendar_event_details": "Ukryj szczegóły wydarzeń w kalendarzu na udostępnionych kalendarzach",
"description_hide_calendar_event_details": "Gdy kalendarz jest udostępniony, wydarzenia są widoczne dla czytelników, ale ich szczegóły są ukryte dla osób bez dostępu do edycji.",
"last_number_of_days": "ostatnie {{count}} dni",
@@ -876,12 +876,17 @@
"copy_private_link": "Copiar link privado",
"copy_private_link_to_event": "Copiar link privado para evento",
"private_link_description": "Gere um URL privado para compartilhar sem expor seu nome de usuário do {{appName}}",
"multiple_private_links_title": "Links Privados",
"multiple_private_links_description": "Gere URLs privadas sem expor o nome de usuário, que serão destruídas após o uso",
"add_a_multiple_private_link": "Adicionar novo link",
"multiple_private_link_copied": "Link privado copiado",
"invitees_can_schedule": "Os convidados podem agendar",
"date_range": "Intervalo de Datas",
"calendar_days": "dias da agenda",
"business_days": "dias úteis",
"set_address_place": "Defina um endereço ou local",
"set_link_meeting": "Defina um link para a reunião",
"managed_event_field_parent_control_disabled": "Não pode ser alternado. Só pode ser desbloqueado para tipos de eventos filhos",
"cal_invitee_phone_number_scheduling": "{{appName}} solicitará ao seu convidado que insira um número de telefone antes de agendar.",
"cal_provide_google_meet_location": "{{appName}} fornecerá um link para o Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} fornecerá uma URL de reunião do Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Enviar um lembrete por e-mail 1 hora antes dos eventos começarem para o participante",
"workflow_example_5": "Enviar e-mail personalizado quando o evento for reagendado para a(o) anfitriã(o)",
"workflow_example_6": "Enviar SMS personalizado quando o novo evento for agendado para a(o) anfitriã(o)",
"count_managed_to_limit": "Incluir contagens de reservas de tipos de eventos gerenciados",
"welcome_to_cal_header": "Bem-vindo(a) à {{appName}}!",
"edit_form_later_subtitle": "Você poderá editar isso mais tarde.",
"connect_calendar_later": "Vou conectar a meu calendário mais tarde",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Coletar taxa de não comparecimento",
"no_show_fee_charged": "Taxa de não comparecimento cobrada",
"insights": "Insights",
"routing_forms": "Formulários de Roteamento",
"testing_workflow_info_message": "Ao testar este fluxo de trabalho, não se esqueça de que e-mails e SMS só podem ser reprogramados com pelo menos uma hora de antecedência",
"insights_no_data_found_for_filter": "Nenhum dado encontrado para o filtro ou dados selecionados.",
"acknowledge_booking_no_show_fee": "Estou ciente de que, se eu não comparecer a este evento, será cobrada no meu cartão uma taxa de não comparecimento de {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configurar sua organização",
"set_up_your_platform_organization": "Configurar sua plataforma",
"organizations_description": "Organizações são ambientes compartilhados em que as equipes podem criar fluxos de trabalho, aplicativos, tipos de evento compartilhados e muito mais.",
"platform": "Plataforma",
"platform_description": "Gerencie tudo relacionado à plataforma.",
"platform_organization_description": "A Plataforma Cal.com permite que você facilmente integre agendadores no seu aplicativo usando APIs e módulos da plataforma.",
"must_enter_organization_name": "Requer um nome de organização",
"must_enter_organization_admin_email": "Requer o endereço de e-mail da sua organização",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Adicione um único cartão de crédito para pagar todas as assinaturas da sua equipe",
"advanced_managed_events": "Tipos de eventos gerenciados avançados",
"advanced_managed_events_description": "Adicione um único cartão de crédito para pagar todas as assinaturas da sua equipe",
"enterprise": "Empresa",
"enterprise_description": "Atualize para Enterprise para criar sua organização",
"create_your_org": "Crie sua organização",
"create_your_org_description": "Atualize para Organizations e receba um subdomínio, faturamento unificado, insights, whitelabeling abrangente e muito mais",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Desativar entrada se o identificador da URL estiver preenchido",
"booking_limits": "Limites de Agendamento",
"booking_limits_team_description": "Limites de agendamento para membros da equipe em todos os tipos de eventos da equipe",
"limit_team_booking_frequency_description": "Limite quantas vezes os membros podem ser agendados em todos os tipos de eventos da equipe (coletivo e round-robin)",
"limit_team_booking_frequency_description": "Limitar quantas vezes os membros podem ser reservados em todos os tipos de eventos da equipe",
"booking_limits_updated_successfully": "Limites de agendamento atualizados com sucesso",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Você não tem autorização para fazer essa alteração na reserva",
"matching_members": "Membros correspondentes",
"no_matching_members": "Nenhum membro correspondente. Será utilizado como alternativa os membros da equipe atribuídos ao tipo de evento.",
"hide_calendar_event_details": "Ocultar detalhes dos eventos do calendário em calendários compartilhados",
"description_hide_calendar_event_details": "Quando um calendário é compartilhado, os eventos são visíveis para os leitores, mas seus detalhes são ocultados para aqueles que não têm acesso de escrita.",
"last_number_of_days": "últimos {{count}} dias",
+13 -1
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copiar ligação privada",
"copy_private_link_to_event": "Copiar ligação privada para o evento",
"private_link_description": "Crie um URL privado para partilhar sem expor o seu nome de utilizador do {{appName}}",
"multiple_private_links_title": "Links Privados",
"multiple_private_links_description": "Gere URLs privadas sem expor o nome de utilizador, que serão destruídas após serem usadas",
"add_a_multiple_private_link": "Adicionar novo link",
"multiple_private_link_copied": "Link privado copiado",
"invitees_can_schedule": "Os convidados podem agendar",
"date_range": "Intervalo de Datas",
"calendar_days": "dias da agenda",
"business_days": "dias úteis",
"set_address_place": "Defina um endereço ou local",
"set_link_meeting": "Definir uma ligação para a reunião",
"managed_event_field_parent_control_disabled": "Não pode ser alternado. Só pode ser desbloqueado para tipos de eventos filhos",
"cal_invitee_phone_number_scheduling": "{{appName}} solicitará ao seu convidado que insira um número de telefone antes de agendar.",
"cal_provide_google_meet_location": "O {{appName}} irá fornecer uma localização do Google Meet.",
"cal_provide_zoom_meeting_url": "O {{appName}} irá fornecer um URL de reunião do Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Enviar lembrete de participação por e-mail 1 hora antes do evento começar",
"workflow_example_5": "Enviar um e-mail personalizado para o participante quando o evento for reagendado",
"workflow_example_6": "Enviar um SMS personalizado para o anfitrião quando um novo evento é agendado",
"count_managed_to_limit": "Incluir contagens de reservas dos tipos de eventos geridos",
"welcome_to_cal_header": "Bem-vindo(a) ao {{appName}}!",
"edit_form_later_subtitle": "Poderá editar isto mais tarde.",
"connect_calendar_later": "Vou associar o meu calendário mais tarde",
@@ -2044,6 +2050,7 @@
"collect_no_show_fee": "Cobrar taxa de não-comparência",
"no_show_fee_charged": "A taxa de não-comparência debitada",
"insights": "Insights",
"routing_forms": "Formulários de Roteamento",
"testing_workflow_info_message": "Ao testar este fluxo de trabalho tenha em consideração que e-mails e SMS só podem ser agendados com, pelo menos, 1 hora de antecedência",
"insights_no_data_found_for_filter": "Não foram encontrados dados para as datas ou filtros selecionados.",
"acknowledge_booking_no_show_fee": "Eu aceito que caso eu não compareça a este evento, será cobrada uma taxa de não-comparência de {{amount, currency}} no meu cartão.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configurar a sua organização",
"set_up_your_platform_organization": "Configurar a sua plataforma",
"organizations_description": "As organizações são ambientes partilhados onde as equipas podem criar tipos de eventos partilhados, aplicações, fluxos de trabalho e muito mais.",
"platform": "Plataforma",
"platform_description": "Gerir tudo relacionado com a plataforma.",
"platform_organization_description": "A plataforma Cal.com permite, de forma muito simples, integrar agendamentos na sua aplicação utilizando APIs e atoms da plataforma.",
"must_enter_organization_name": "Deve indicar um nome para a organização",
"must_enter_organization_admin_email": "Deve indicar o endereço de e-mail da sua organização",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Adicione um único cartão de crédito para pagar todas as subscrições da sua equipa",
"advanced_managed_events": "Tipos de evento geridos avançados",
"advanced_managed_events_description": "Adicione um único cartão de crédito para pagar todas as subscrições da sua equipa",
"enterprise": "Empresa",
"enterprise_description": "Atualize para Enterprise para criar a sua Organização",
"create_your_org": "Crie a sua Organização",
"create_your_org_description": "Atualize para Organizations e receba um subdomínio, faturação unificada, Insights, personalização abrangente da imagem corporativa e muito mais",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Desativar entrada se o identificador de URL estiver pré-preenchido",
"booking_limits": "Limites de Reservas",
"booking_limits_team_description": "Limites de reservas para membros da equipa em todos os tipos de eventos da equipa",
"limit_team_booking_frequency_description": "Limite quantas vezes os membros podem ser reservados em todos os tipos de eventos da equipa (coletivo e round-robin)",
"limit_team_booking_frequency_description": "Limitar quantas vezes os membros podem ser reservados em todos os tipos de eventos da equipa",
"booking_limits_updated_successfully": "Limites de reservas atualizados com sucesso",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Não tem autorização para fazer esta alteração na reserva",
"matching_members": "Membros correspondentes",
"no_matching_members": "Nenhum membro correspondente. Será utilizado como alternativa os membros da equipa atribuídos ao tipo de evento.",
"hide_calendar_event_details": "Ocultar detalhes dos eventos do calendário em calendários partilhados",
"description_hide_calendar_event_details": "Quando um calendário é partilhado, os eventos são visíveis para os leitores, mas os seus detalhes são ocultados para aqueles que não têm acesso de escrita.",
"last_number_of_days": "últimos {{count}} dias",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Copiere link privat",
"copy_private_link_to_event": "Copiază linkul privat către eveniment",
"private_link_description": "Generați un URL privat pentru distribuire fără expunerea numelui de utilizator {{appName}}",
"multiple_private_links_title": "Linkuri Private",
"multiple_private_links_description": "Generează URL-uri private fără a expune numele de utilizator, care vor fi distruse după utilizare",
"add_a_multiple_private_link": "Adaugă un link nou",
"multiple_private_link_copied": "Linkul privat a fost copiat",
"invitees_can_schedule": "Invitații pot programa",
"date_range": "Interval de date",
"calendar_days": "zile calendaristice",
"business_days": "zile lucrătoare",
"set_address_place": "Setați o adresă sau un loc",
"set_link_meeting": "Definiți un link pentru ședință",
"managed_event_field_parent_control_disabled": "Nu poate fi comutat. Poate fi deblocat doar pentru tipurile de evenimente copil",
"cal_invitee_phone_number_scheduling": "{{appName}} va cere invitatului dvs. să introducă un număr de telefon înainte de programare.",
"cal_provide_google_meet_location": "{{appName}} va oferi o locație Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} va oferi un URL pentru ședința de Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Trimiteți participantului un memento prin e-mail cu 1 oră înainte de începerea evenimentului",
"workflow_example_5": "Trimiteți gazdei un e-mail personalizat atunci când evenimentul nou este reprogramat",
"workflow_example_6": "Trimiteți gazdei un SMS personalizat atunci când evenimentul nou este rezervat",
"count_managed_to_limit": "Include numărul de rezervări din tipurile de evenimente gestionate",
"welcome_to_cal_header": "Bun venit pe {{appName}}!",
"edit_form_later_subtitle": "Veți putea efectua modificări mai târziu.",
"connect_calendar_later": "Îmi voi conecta calendarul mai târziu",
@@ -2043,7 +2049,8 @@
"error_charging_card": "A survenit o eroare la perceperea taxei de neprezentare. Încercați din nou mai târziu.",
"collect_no_show_fee": "Colectare taxă de neprezentare",
"no_show_fee_charged": "Taxă de neprezentare percepută",
"insights": "Insights",
"insights": "Informații",
"routing_forms": "Formulare de Rutare",
"testing_workflow_info_message": "La testarea acestui flux de lucru, țineți cont de faptul că e-mailurile și SMS-urile pot fi programate doar cu cel puțin o oră în prealabil",
"insights_no_data_found_for_filter": "Nu s-au găsit date pentru filtrul selectat sau pentru datele selectate.",
"acknowledge_booking_no_show_fee": "Dacă nu particip la acest eveniment, accept să mi se perceapă de pe card o taxă de neprezentare în valoare de {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Configurați organizația",
"set_up_your_platform_organization": "Configurează-ți platforma",
"organizations_description": "Organizațiile sunt medii partajate în care echipele pot crea tipuri de evenimente, aplicații, fluxuri de lucru comune și multe altele.",
"platform": "Platformă",
"platform_description": "Gestionează tot ce ține de platformă.",
"platform_organization_description": "Platforma Cal.com îți permite să integrezi programarea fără efort în aplicația ta folosind API-uri și atomi de platformă.",
"must_enter_organization_name": "Trebuie să introduceți denumirea unei organizații",
"must_enter_organization_admin_email": "Trebuie să introduceți adresa de e-mail a organizației",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Adăugați un singur card de credit pentru a plăti toate abonamentele echipei dvs.",
"advanced_managed_events": "Tipuri Avansate de Evenimente Gestionate",
"advanced_managed_events_description": "Adăugați un singur card de credit pentru a plăti toate abonamentele echipei dvs.",
"enterprise": "Întreprindere",
"enterprise_description": "Faceți upgrade la Enterprise pentru a crea organizația dvs.",
"create_your_org": "Creați-vă Organizația",
"create_your_org_description": "Faceți upgrade la Organizații și primiți un subdomeniu, facturare unificată, Insights, whitelabeling extins și altele",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Dezactivează introducerea dacă identificatorul URL este precompletat",
"booking_limits": "Limite de rezervare",
"booking_limits_team_description": "Limite de rezervare pentru membrii echipei pentru toate tipurile de evenimente ale echipei",
"limit_team_booking_frequency_description": "Limitează de câte ori pot fi rezervați membrii pentru toate tipurile de evenimente ale echipei (colective și round-robin)",
"limit_team_booking_frequency_description": "Limitează de câte ori pot fi rezervați membrii în toate tipurile de evenimente ale echipei",
"booking_limits_updated_successfully": "Limitele de rezervare au fost actualizate cu succes",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Nu aveți autorizația necesară pentru a face această modificare în rezervare",
"matching_members": "Membri corespunzători",
"no_matching_members": "Nu există membri corespunzători. Se va reveni la utilizarea membrilor echipei alocați tipului de eveniment.",
"hide_calendar_event_details": "Ascunde detaliile evenimentelor din calendar pe calendarele partajate",
"description_hide_calendar_event_details": "Când un calendar este partajat, evenimentele sunt vizibile pentru cititori, dar detaliile lor sunt ascunse celor fără acces de scriere.",
"last_number_of_days": "ultimele {{count}} zile",
@@ -2034,7 +2034,6 @@
"error_charging_card": "Не удалось списать комиссию за неявку. Повторите попытку позже.",
"collect_no_show_fee": "Списать комиссию за неявку",
"no_show_fee_charged": "Комиссия за неявку списана",
"insights": "Insights",
"testing_workflow_info_message": "При тестировании этого рабочего процесса помните, что отправку писем и SMS можно запланировать не менее чем за 1 час до начала",
"insights_no_data_found_for_filter": "Данные, соответствующие выбранному фильтру или диапазону дат, не найдены.",
"acknowledge_booking_no_show_fee": "Я подтверждаю, что в случае моей неявки на событие с моей карты будет списана комиссия в размере {{amount, currency}}.",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Kopiraj privatni link",
"copy_private_link_to_event": "Kopiraj privatni link do događaja",
"private_link_description": "Generiši privatni URL za deljenje bez prikazivanja vašeg {{appName}} korisničkog imena",
"multiple_private_links_title": "Privatni linkovi",
"multiple_private_links_description": "Generišite privatne URL adrese bez otkrivanja korisničkog imena, koje će biti uništene nakon korišćenja",
"add_a_multiple_private_link": "Dodaj novi link",
"multiple_private_link_copied": "Privatni link je kopiran",
"invitees_can_schedule": "Pozvane osobe mogu da rezervišu",
"date_range": "Raspon Datuma",
"calendar_days": "kalendarska dana",
"business_days": "radna dana",
"set_address_place": "Postavite adresu ili mesto",
"set_link_meeting": "Postavi link za sastanak",
"managed_event_field_parent_control_disabled": "Ne može se menjati. Može se otključati samo za podređene tipove događaja",
"cal_invitee_phone_number_scheduling": "{{appName}} će pitati pozvane da unesu broj telefona pre rezervisanja.",
"cal_provide_google_meet_location": "{{appName}} će obezbediti Google Meet link.",
"cal_provide_zoom_meeting_url": "{{appName}} će obezbediti URL Zoom sastanka.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Pošalji imejl podsetnik učesniku jedan sat pre početka događaja",
"workflow_example_5": "Pošalji prilagođeni imejl domaćinu kada je događaju promenjeno vreme",
"workflow_example_6": "Pošalji prilagođeni SMS domaćinu kada je novi događaj rezervisan",
"count_managed_to_limit": "Uključi broj rezervacija iz upravljanih tipova događaja",
"welcome_to_cal_header": "Dobrodošli na {{appName}}!",
"edit_form_later_subtitle": "Ovo ćete moći da izmenite kasnije.",
"connect_calendar_later": "Povezaću svoj kalendar kasnije",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Došlo je do greške prilikom naplate naknade za izostanak. Pokušajte ponovo kasnije.",
"collect_no_show_fee": "Prikupi naknadu za izostanak",
"no_show_fee_charged": "Naplaćena je naknada za izostanak",
"insights": "Insights",
"insights": "Uvidi",
"routing_forms": "Obrasci za usmeravanje",
"testing_workflow_info_message": "Kada testirate ovaj radni tok, imajte na umu da imejlovi i SMS-ovi mogu da budu zakazani najmanje 1 sat unapred",
"insights_no_data_found_for_filter": "Nisu pronađeni podaci za izabrani filter ili izabrane datume.",
"acknowledge_booking_no_show_fee": "Jasno mi je da će mi biti naplaćena naknada za izostanak putem kartice u iznosu od {{amount, currency}} ukoliko ne prisustvujem ovom događaju.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Konfigurisanje profila organizacije",
"set_up_your_platform_organization": "Postavite svoju platformu",
"organizations_description": "Organizacije su deljena okruženja gde timovi mogu da kreiraju deljene vrste događaja, aplikacije, radne tokove i još mnogo toga.",
"platform": "Platforma",
"platform_description": "Upravljajte svim što je povezano sa platformom.",
"platform_organization_description": "Cal.com platforma vam omogućava da lako integrišete zakazivanje u vašu aplikaciju koristeći platform API-je i atome.",
"must_enter_organization_name": "Morate da unesete naziv organizacije",
"must_enter_organization_admin_email": "Morate da unesete adresu e-pošte vaše organizacije",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Dodajte jednu kreditnu karticu za plaćanje svih pretplata vašeg tima",
"advanced_managed_events": "Napredni tipovi upravljanih događaja",
"advanced_managed_events_description": "Dodajte jednu kreditnu karticu za plaćanje svih pretplata vašeg tima",
"enterprise": "Preduzeće",
"enterprise_description": "Nadogradite na Enterprise da biste kreirali svoju organizaciju",
"create_your_org": "Kreirajte svoju organizaciju",
"create_your_org_description": "Nadogradite na organizacije i dobijte poddomen, jedinstveno naplaćivanje, Insights, opsežno prilagođavanje i još mnogo toga",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Onemogući unos ako je URL identifikator unapred popunjen",
"booking_limits": "Ograničenja zakazivanja",
"booking_limits_team_description": "Ograničenja zakazivanja za članove tima za sve vrste timskih događaja",
"limit_team_booking_frequency_description": "Ograničite koliko puta članovi mogu biti zakazani za sve vrste timskih događaja (kolektivne i round-robin)",
"limit_team_booking_frequency_description": "Ograniči koliko puta članovi tima mogu biti rezervisani za sve timske tipove događaja",
"booking_limits_updated_successfully": "Ograničenja zakazivanja su uspešno ažurirana",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Nemate ovlašćenje da izvršite ovu promenu u rezervaciji",
"matching_members": "Одговарајући чланови",
"no_matching_members": "Нема одговарајућих чланова. Систем ће се вратити на коришћење чланова тима додељених типу догађаја.",
"hide_calendar_event_details": "Sakrij detalje događaja u deljenim kalendarima",
"description_hide_calendar_event_details": "Kada je kalendar podeljen, događaji su vidljivi čitaocima, ali su njihovi detalji skriveni od onih koji nemaju pravo izmene.",
"last_number_of_days": "poslednjih {{count}} dana",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Kopiera privat länk",
"copy_private_link_to_event": "Kopiera privat länk till händelse",
"private_link_description": "Generera en privat URL att dela utan att exponera ditt {{appName}}-användarnamn",
"multiple_private_links_title": "Privata länkar",
"multiple_private_links_description": "Generera privata URL:er utan att exponera användarnamnet, som kommer att förstöras efter användning",
"add_a_multiple_private_link": "Lägg till ny länk",
"multiple_private_link_copied": "Privat länk kopierad",
"invitees_can_schedule": "Inbjudna kan schemalägga",
"date_range": "Datumintervall",
"calendar_days": "kalenderdagar",
"business_days": "arbetsdagar",
"set_address_place": "Ange adress eller plats",
"set_link_meeting": "Ange en länk till mötet",
"managed_event_field_parent_control_disabled": "Kan inte växlas. Det kan endast låsas upp för underordnade händelsetyper",
"cal_invitee_phone_number_scheduling": "{{appName}} kommer be den inbjudna att ange ett telefonnummer innan schemaläggning.",
"cal_provide_google_meet_location": "{{appName}} kommer att generera en Google Meet länk.",
"cal_provide_zoom_meeting_url": "{{appName}} kommer att generera en länk för Zoom-möte.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Skicka en e-postpåminnelse till deltagare 1 timme innan händelsen startar",
"workflow_example_5": "Skicka anpassat e-postmeddelande till värd när händelsen bokas om",
"workflow_example_6": "Skicka anpassat SMS till värd när ny händelse bokas",
"count_managed_to_limit": "Inkludera bokningsantal från hanterade händelsetyper",
"welcome_to_cal_header": "Välkommen till {{appName}}!",
"edit_form_later_subtitle": "Du kan redigera detta senare.",
"connect_calendar_later": "Jag ansluter min kalender senare",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Något gick fel när avgiften för utebliven närvaro debiterades. Försök igen senare.",
"collect_no_show_fee": "Samla in avgift för utebliven närvaro",
"no_show_fee_charged": "Avgift för utebliven närvaro har debiterats",
"insights": "Insights",
"insights": "Insikter",
"routing_forms": "Routningsformulär",
"testing_workflow_info_message": "När det här arbetsflödet testas ska du vara medveten om att e-postmeddelanden och SMS endast kan schemaläggas minst en timme i förväg",
"insights_no_data_found_for_filter": "Inga data hittades för valt filter eller valda datum.",
"acknowledge_booking_no_show_fee": "Jag bekräftar att en avgift på {{amount, currency}} för utebliven närvaro debiteras mitt kort om jag inte deltar i händelsen.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Konfigurera din organisation",
"set_up_your_platform_organization": "Ställ in din plattform",
"organizations_description": "Organisationer är delade miljöer där team kan skapa delade händelsetyper, appar, arbetsflöden och mycket mer.",
"platform": "Plattform",
"platform_description": "Hantera allt som rör plattformen.",
"platform_organization_description": "Cal.com-plattformen låter dig integrera schemaläggning smidigt i din app med hjälp av plattformens API:er och atomer.",
"must_enter_organization_name": "Ett organisationsnamn måste anges",
"must_enter_organization_admin_email": "En organisations e-postadress måste anges",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Lägg till ett enda kreditkort för att betala för alla dina teams prenumerationer",
"advanced_managed_events": "Avancerade Hanterade Eventtyper",
"advanced_managed_events_description": "Lägg till ett enda kreditkort för att betala för alla dina teams prenumerationer",
"enterprise": "Företag",
"enterprise_description": "Uppgradera till Enterprise för att skapa din organisation",
"create_your_org": "Skapa din Organisation",
"create_your_org_description": "Uppgradera till Organisationer och få en subdomän, enhetlig fakturering, Insights, omfattande whitelabeling och mer",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Inaktivera inmatning om URL-identifieraren är förifylld",
"booking_limits": "Bokningsgränser",
"booking_limits_team_description": "Bokningsgränser för teammedlemmar för alla typer av teamhändelser",
"limit_team_booking_frequency_description": "Begränsa hur många gånger medlemmar kan bokas för alla typer av teamhändelser (kollektivt och round-robin)",
"limit_team_booking_frequency_description": "Begränsa hur många gånger medlemmar kan bokas över alla teamhändelsetyper",
"booking_limits_updated_successfully": "Bokningsgränser uppdaterades framgångsrikt",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Du har inte behörighet att göra denna ändring i bokningen",
"matching_members": "Matchande medlemmar",
"no_matching_members": "Inga matchande medlemmar. Det kommer att återgå till att använda de teammedlemmar som är tilldelade till händelsetypen.",
"hide_calendar_event_details": "Dölj kalenderhändelsedetaljer på delade kalendrar",
"description_hide_calendar_event_details": "När en kalender delas är händelser synliga för läsare, men deras detaljer är dolda för dem utan skrivåtkomst.",
"last_number_of_days": "senaste {{count}} dagarna",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Özel bağlantıyı kopyala",
"copy_private_link_to_event": "Etkinliğe özel bağlantıyı kopyala",
"private_link_description": "{{appName}} kullanıcı adınızı göstermeden paylaşmak için özel bir URL oluşturun",
"multiple_private_links_title": "Özel Bağlantılar",
"multiple_private_links_description": "Kullanıcı adını açığa çıkarmadan özel URL'ler oluşturun, bu bağlantılar kullanıldıktan sonra yok edilecektir",
"add_a_multiple_private_link": "Yeni bağlantı ekle",
"multiple_private_link_copied": "Özel bağlantı kopyalandı",
"invitees_can_schedule": "Davetliler planlayabilir",
"date_range": "Tarih Aralığı",
"calendar_days": "takvim günü",
"business_days": "iş günü",
"set_address_place": "Bir adres veya yer belirleyin",
"set_link_meeting": "Toplantı için bir bağlantı ayarlayın",
"managed_event_field_parent_control_disabled": "Değiştirilemez. Sadece alt etkinlik türleri için kilidi açılabilir",
"cal_invitee_phone_number_scheduling": "{{appName}}, planlamadan önce davetlinizden bir telefon numarası girmesini isteyecektir.",
"cal_provide_google_meet_location": "{{appName}}, bir Google Meet konumu sağlayacaktır.",
"cal_provide_zoom_meeting_url": "{{appName}}, bir Zoom toplantı URL'si sağlayacaktır.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Etkinlikler başlamadan 1 saat önce katılımcıya e-posta hatırlatıcısı gönder",
"workflow_example_5": "Etkinlik yeniden planlandığında etkinlik sahibine özel e-posta gönder",
"workflow_example_6": "Yeni bir etkinlik rezervasyonu yapıldığında organizatöre özel SMS gönder",
"count_managed_to_limit": "Yönetilen etkinlik türlerinden rezervasyon sayılarını dahil et",
"welcome_to_cal_header": "{{appName}}'a hoş geldiniz!",
"edit_form_later_subtitle": "Bunu daha sonra düzenleyebilirsiniz.",
"connect_calendar_later": "Takvimimi daha sonra bağlayacağım",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Katılmama ücreti alınırken bir sorun oluştu. Lütfen daha sonra tekrar deneyin.",
"collect_no_show_fee": "Katılmama ücretini tahsil edin",
"no_show_fee_charged": "Katılmama ücreti tahsil edildi",
"insights": "Insights",
"insights": "Öngörüler",
"routing_forms": "Yönlendirme Formları",
"testing_workflow_info_message": "Bu iş akışını test ederken, E-postaların ve SMS'lerin yalnızca en az 1 saat önceden planlanabileceğini unutmayın",
"insights_no_data_found_for_filter": "Seçili filtre veya tarihler için veri bulunamadı.",
"acknowledge_booking_no_show_fee": "Bu etkinliğe katılmadığım takdirde kartımdan {{amount, currency}} tutarında katılmama ücreti alınmasını kabul ediyorum.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Kuruluşunuzu düzenleyin",
"set_up_your_platform_organization": "Platformunuzu kurun",
"organizations_description": "Kuruluşlar, ekiplerin paylaşımlı etkinlik türleri, uygulamalar, iş akışları ve daha fazlasını oluşturabileceği paylaşımlı ortamlardır.",
"platform": "Platform",
"platform_description": "Platformla ilgili her şeyi yönetin.",
"platform_organization_description": "Cal.com Platformu, platform API'leri ve atomları kullanarak planlamayı uygulamanıza zahmetsizce entegre etmenizi sağlar.",
"must_enter_organization_name": "Kuruluş adı girilmeli",
"must_enter_organization_admin_email": "Kuruluşunuzun e-posta adresini girmelisiniz",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Tüm takım abonelikleriniz için tek bir kredi kartı ekleyin",
"advanced_managed_events": "Gelişmiş Yönetilen Etkinlik Türleri",
"advanced_managed_events_description": "Tüm takım abonelikleriniz için tek bir kredi kartı ekleyin",
"enterprise": "Kurumsal",
"enterprise_description": "Organizasyonunuzu oluşturmak için Enterprise'a yükseltin",
"create_your_org": "Organizasyonunuzu Oluşturun",
"create_your_org_description": "Organizasyonlara yükseltin ve bir alt alan adı, birleşik faturalama, Insights, kapsamlı beyaz etiketleme ve daha fazlasını alın",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "URL tanımlayıcısı önceden doldurulmuşsa girişi devre dışı bırak",
"booking_limits": "Rezervasyon Sınırları",
"booking_limits_team_description": "Tüm ekip etkinlik türleri için ekip üyeleri için rezervasyon sınırları",
"limit_team_booking_frequency_description": "Ekip üyelerinin tüm ekip etkinlik türlerinde (kolektif ve round-robin) kaç kez rezerve edilebileceğini sınırlayın",
"limit_team_booking_frequency_description": "Tüm ekip etkinlik türlerinde üyelerin kaç kez rezerve edilebileceğini sınırlayın",
"booking_limits_updated_successfully": "Rezervasyon sınırları başarıyla güncellendi",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Bu rezervasyonda değişiklik yapma yetkiniz yok",
"matching_members": "Eşleşen üyeler",
"no_matching_members": "Eşleşen üye yok. Etkinlik türüne atanan takım üyeleri kullanılacaktır.",
"hide_calendar_event_details": "Paylaşılan takvimlerde etkinlik ayrıntılarını gizle",
"description_hide_calendar_event_details": "Bir takvim paylaşıldığında, etkinlikler okuyuculara görünür ancak yazma erişimi olmayanlar için ayrıntılar gizlenir.",
"last_number_of_days": "son {{count}} gün",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Копіювати приватне посилання",
"copy_private_link_to_event": "Скопіювати приватне посилання на подію",
"private_link_description": "Створіть приватну URL-адресу, щоб поширювати її, не виказуючи свого імені користувача в {{appName}}",
"multiple_private_links_title": "Приватні посилання",
"multiple_private_links_description": "Створюйте приватні URL-адреси без розкриття імені користувача, які будуть знищені після використання",
"add_a_multiple_private_link": "Додати нове посилання",
"multiple_private_link_copied": "Приватне посилання скопійовано",
"invitees_can_schedule": "Запрошені можуть планувати",
"date_range": "Діапазон дат",
"calendar_days": "календарні дні",
"business_days": "робочі дні",
"set_address_place": "Укажіть адресу або місце",
"set_link_meeting": "Створити посилання на нараду",
"managed_event_field_parent_control_disabled": "Не можна перемикати. Можна розблокувати лише для дочірніх типів подій",
"cal_invitee_phone_number_scheduling": "У {{appName}} запрошеним знадобиться ввести номер телефону, перш ніж планувати щось.",
"cal_provide_google_meet_location": "{{appName}} надасть розташування Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} надасть URL-адресу наради Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Надсилати учаснику нагадування про захід електронною поштою за 1 годину до початку",
"workflow_example_5": "Надсилати ведучому персоналізований електронний лист у разі перенесення заходу",
"workflow_example_6": "Надсилати ведучому персоналізоване SMS у разі бронювання нового заходу",
"count_managed_to_limit": "Включити кількість бронювань з керованих типів подій",
"welcome_to_cal_header": "Вітаємо в {{appName}}!",
"edit_form_later_subtitle": "Це можна буде змінити пізніше.",
"connect_calendar_later": "Я підключу календар пізніше",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Сталася помилка під час стягнення плати за відсутність. Спробуйте пізніше.",
"collect_no_show_fee": "Стягнути плату за відсутність",
"no_show_fee_charged": "Стягнуто плату за відсутність",
"insights": "Insights",
"insights": "Аналітика",
"routing_forms": "Форми маршрутизації",
"testing_workflow_info_message": "Тестуючи цей робочий процес, зважайте на те, що надсилання електронних листів і SMS-повідомлень можна запланувати щонайменше за 1 годину",
"insights_no_data_found_for_filter": "Не знайдено жодних даних для вибраного фільтра або вибраних дат.",
"acknowledge_booking_no_show_fee": "Я усвідомлюю, що в разі моєї відсутності на цьому заході з моєї картки буде стягнуто плату в розмірі {{amount, currency}}.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Налаштуйте свою організацію",
"set_up_your_platform_organization": "Налаштуйте свою платформу",
"organizations_description": "Організації — це спільне середовище, де команди можуть створювати спільні типи заходів, застосунки, робочі процеси тощо.",
"platform": "Платформа",
"platform_description": "Керуйте всім, що стосується платформи.",
"platform_organization_description": "Платформа Cal.com дозволяє легко інтегрувати планування у ваш додаток за допомогою API та атомів платформи.",
"must_enter_organization_name": "Потрібно ввести назву організації",
"must_enter_organization_admin_email": "Потрібно ввести електронну адресу організації",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Додайте одну кредитну картку для оплати всіх підписок вашої команди",
"advanced_managed_events": "Розширені керовані типи подій",
"advanced_managed_events_description": "Додайте одну кредитну картку для оплати всіх підписок вашої команди",
"enterprise": "Підприємство",
"enterprise_description": "Оновіть до Enterprise, щоб створити свою організацію",
"create_your_org": "Створіть свою організацію",
"create_your_org_description": "Оновіть до Організацій і отримайте піддомен, єдине виставлення рахунків, інсайти, розширене налаштування брендування та інше",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Вимкнути введення, якщо ідентифікатор URL попередньо заповнений",
"booking_limits": "Обмеження бронювання",
"booking_limits_team_description": "Обмеження бронювання для членів команди для всіх типів командних подій",
"limit_team_booking_frequency_description": "Обмежте кількість разів, коли члени можуть бути заброньовані для всіх типів командних подій (колективних та round-robin)",
"limit_team_booking_frequency_description": "Обмежити, скільки разів учасників можна забронювати для всіх типів командних подій",
"booking_limits_updated_successfully": "Обмеження бронювання успішно оновлено",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Ви не маєте дозволу на внесення цієї зміни до бронювання",
"matching_members": "Відповідні учасники",
"no_matching_members": "Відповідних учасників немає. Буде використано учасників команди, призначених для цього типу події.",
"hide_calendar_event_details": "Приховати деталі подій календаря у спільних календарях",
"description_hide_calendar_event_details": "Коли календар спільний, події видимі для читачів, але їхні деталі приховані для тих, хто не має прав на редагування.",
"last_number_of_days": "останні {{count}} днів",
+14 -2
View File
@@ -876,12 +876,17 @@
"copy_private_link": "Sao chép liên kết riêng",
"copy_private_link_to_event": "Sao chép liên kết riêng tư đến sự kiện",
"private_link_description": "Tạo một URL riêng tư để chia sẻ mà không tiết lộ tên người dùng {{appName}} của bạn",
"multiple_private_links_title": "Liên kết Riêng tư",
"multiple_private_links_description": "Tạo các URL riêng tư mà không tiết lộ tên người dùng, sẽ bị hủy sau khi sử dụng",
"add_a_multiple_private_link": "Thêm liên kết mới",
"multiple_private_link_copied": "Liên kết riêng tư đã được sao chép",
"invitees_can_schedule": "Người được mời có thể lên lịch hẹn",
"date_range": "Phạm vi ngày",
"calendar_days": "ngày",
"business_days": "ngày làm việc",
"set_address_place": "Đặt địa chỉ hoặc địa điểm",
"set_link_meeting": "Đặt liên kết đến cuộc họp",
"managed_event_field_parent_control_disabled": "Không thể chuyển đổi. Chỉ có thể mở khóa cho các loại sự kiện con",
"cal_invitee_phone_number_scheduling": "{{appName}} sẽ yêu cầu người được mời nhập số điện thoại trước khi lên lịch.",
"cal_provide_google_meet_location": "{{appName}} sẽ cung cấp URL Google Meet.",
"cal_provide_zoom_meeting_url": "{{appName}} sẽ cung cấp một URL cuộc họp Zoom.",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "Gửi lời nhắc email cho người tham gia 1 giờ trước khi bắt đầu sự kiện",
"workflow_example_5": "Gửi email tuỳ chỉnh cho chủ sự kiện khi sự kiện được sắp lịch lại",
"workflow_example_6": "Gửi SMS tuỳ chỉnh cho chủ sự kiện khi sự kiện mới được đặt lịch hẹn",
"count_managed_to_limit": "Bao gồm số lượng đặt chỗ từ các loại sự kiện được quản lý",
"welcome_to_cal_header": "Chào mừng đến với {{appName}}!",
"edit_form_later_subtitle": "Bạn có thể sửa lại thông tin này sau.",
"connect_calendar_later": "Tôi sẽ kết nối lịch của mình sau",
@@ -2043,7 +2049,8 @@
"error_charging_card": "Có sự cố khi tính phí vắng mặt. Vui lòng thử lại sau.",
"collect_no_show_fee": "Thu phí vắng mặt",
"no_show_fee_charged": "Phí vắng mặt đã tính",
"insights": "Insights",
"insights": "Thông tin chi tiết",
"routing_forms": "Biểu mẫu Định tuyến",
"testing_workflow_info_message": "Khi kiểm tra tiến độ công việc này, hãy để ý rằng Email và SMS chỉ có thể được đặt lịch trước ít nhất 1 giờ",
"insights_no_data_found_for_filter": "Không tìm thấy dữ liệu cho bộ lọc hay ngày đã chọn.",
"acknowledge_booking_no_show_fee": "Tôi công nhận là nếu tôi không tham dự sự kiện này thì một khoản phí vắng mặt là {{amount, currency}} sẽ được áp dụng cho thẻ của tôi.",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "Thiết lập tổ chức của bạn",
"set_up_your_platform_organization": "Thiết lập nền tảng của bạn",
"organizations_description": "Tổ chức là môi trường chia sẻ tại đó các nhóm có thể tạo loại sự kiện, ứng dụng, tiến độ công việc, v.v. để dùng chung.",
"platform": "Nền tảng",
"platform_description": "Quản lý mọi thứ liên quan đến nền tảng.",
"platform_organization_description": "Nền tảng Cal.com cho phép bạn tích hợp việc lên lịch một cách dễ dàng vào ứng dụng của bạn bằng cách sử dụng các API và atoms của nền tảng.",
"must_enter_organization_name": "Cần phải nhập tên tổ chức",
"must_enter_organization_admin_email": "Cần phải nhập địa chỉ email của tổ chức",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "Thêm một thẻ tín dụng để thanh toán cho tất cả các đăng ký của nhóm bạn",
"advanced_managed_events": "Loại sự kiện quản lý nâng cao",
"advanced_managed_events_description": "Thêm một thẻ tín dụng để thanh toán cho tất cả các đăng ký của nhóm bạn",
"enterprise": "Doanh nghiệp",
"enterprise_description": "Nâng cấp lên Enterprise để tạo Tổ chức của bạn",
"create_your_org": "Tạo Tổ chức của bạn",
"create_your_org_description": "Nâng cấp lên Tổ chức và nhận một tên miền phụ, thanh toán hợp nhất, Insights, nhãn trắng mở rộng và nhiều hơn nữa",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "Vô hiệu hóa đầu vào nếu URL đã được điền trước",
"booking_limits": "Giới hạn đặt lịch",
"booking_limits_team_description": "Giới hạn đặt lịch cho các thành viên trong nhóm trên tất cả các loại sự kiện của nhóm",
"limit_team_booking_frequency_description": "Giới hạn số lần các thành viên có thể được đặt lịch trên tất cả các loại sự kiện của nhóm (tập thể và round-robin)",
"limit_team_booking_frequency_description": "Giới hạn số lần các thành viên có thể được đặt chỗ trên tất cả các loại sự kiện của nhóm",
"booking_limits_updated_successfully": "Giới hạn đặt lịch đã được cập nhật thành công",
"you_are_unauthorized_to_make_this_change_to_the_booking": "Bạn không có quyền thực hiện thay đổi này đối với đặt chỗ",
"matching_members": "Thành viên phù hợp",
"no_matching_members": "Không có thành viên phù hợp. Hệ thống sẽ sử dụng các thành viên trong nhóm được chỉ định cho loại sự kiện.",
"hide_calendar_event_details": "Ẩn chi tiết sự kiện trên lịch chia sẻ",
"description_hide_calendar_event_details": "Khi một lịch được chia sẻ, các sự kiện sẽ hiển thị cho người xem nhưng chi tiết của chúng sẽ bị ẩn đối với những người không có quyền chỉnh sửa.",
"last_number_of_days": "{{count}} ngày qua",
@@ -876,12 +876,17 @@
"copy_private_link": "复制私有链接",
"copy_private_link_to_event": "复制私有链接到事件",
"private_link_description": "生成私有链接,以在分享时不暴露您的 {{appName}} 用户名",
"multiple_private_links_title": "私密链接",
"multiple_private_links_description": "生成不暴露用户名的私密URL,使用后将被销毁",
"add_a_multiple_private_link": "添加新链接",
"multiple_private_link_copied": "私密链接已复制",
"invitees_can_schedule": "受邀者可以安排",
"date_range": "日期范围",
"calendar_days": "自然日",
"business_days": "工作日",
"set_address_place": "设置地址或位置",
"set_link_meeting": "设置会议链接",
"managed_event_field_parent_control_disabled": "无法切换。只能为子事件类型解锁",
"cal_invitee_phone_number_scheduling": "{{appName}} 将要求您的受邀者在安排时间之前提供电话号码。",
"cal_provide_google_meet_location": "{{appName}} 将提供 Google Meet 位置。",
"cal_provide_zoom_meeting_url": "{{appName}}将提供 Zoom 会议链接",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "在活动开始前 1 小时向参与者发送电子邮件提醒",
"workflow_example_5": "重新安排活动后向主持人发送自定义电子邮件",
"workflow_example_6": "预约新活动后向主持人发送自定义短信",
"count_managed_to_limit": "包括来自管理事件类型的预订次数",
"welcome_to_cal_header": "欢迎访问 {{appName}}!",
"edit_form_later_subtitle": "您稍后可对此进行编辑。",
"connect_calendar_later": "我将稍后连接我的日历",
@@ -2043,7 +2049,8 @@
"error_charging_card": "收取失约费时出错。请稍后再试。",
"collect_no_show_fee": "收取失约费",
"no_show_fee_charged": "已收取失约费",
"insights": "Insights",
"insights": "洞察",
"routing_forms": "路由表单",
"testing_workflow_info_message": "测试此工作流程时请注意,电子邮件和短信必须提前至少 1 小时安排",
"insights_no_data_found_for_filter": "未找到所选筛选器或所选日期的数据。",
"acknowledge_booking_no_show_fee": "我同意,如果我不参加此活动,将从我的卡中收取 {{amount, currency}} 的失约费。",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "设置您的组织",
"set_up_your_platform_organization": "设置您的平台",
"organizations_description": "组织是一种共享环境,团队可以在其中创建共享的活动类型、应用、工作流程等。",
"platform": "平台",
"platform_description": "管理与平台相关的所有内容。",
"platform_organization_description": "Cal.com平台让您可以使用平台API和原子轻松将调度集成到您的应用中。",
"must_enter_organization_name": "必须输入组织名称",
"must_enter_organization_admin_email": "必须输入您组织的电子邮件地址",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "添加一张信用卡来支付您团队的所有订阅费用",
"advanced_managed_events": "高级托管事件类型",
"advanced_managed_events_description": "添加一张信用卡来支付您团队的所有订阅费用",
"enterprise": "企业",
"enterprise_description": "升级到企业版以创建您的组织",
"create_your_org": "创建您的组织",
"create_your_org_description": "升级到企业版获得子域名、统一计费、分析见解、全面的白标功能等等",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "如果 URL 标识符已预填,则禁用输入",
"booking_limits": "预订限制",
"booking_limits_team_description": "所有团队活动类型的团队成员预订限制",
"limit_team_booking_frequency_description": "限制团队成员在所有团队活动类型(集体和round-robin)中的预订次数",
"limit_team_booking_frequency_description": "限制团队成员在所有团队事件类型中被预订的次数",
"booking_limits_updated_successfully": "预订限制更新成功",
"you_are_unauthorized_to_make_this_change_to_the_booking": "您无权对此预订进行更改",
"matching_members": "匹配的成员",
"no_matching_members": "没有匹配的成员。将回退到使用分配给事件类型的团队成员。",
"hide_calendar_event_details": "隐藏共享日历中的事件详情",
"description_hide_calendar_event_details": "当日历被共享时,事件对读者可见,但其详情对没有写入权限的人隐藏。",
"last_number_of_days": "过去{{count}}天",
@@ -876,12 +876,17 @@
"copy_private_link": "複製不公開連結",
"copy_private_link_to_event": "複製活動的私人連結",
"private_link_description": "產生不公開的網址與他人分享,而無須暴露您的 {{appName}} 使用者名稱",
"multiple_private_links_title": "私人連結",
"multiple_private_links_description": "生成不暴露用戶名的私人網址,使用後將被銷毀",
"add_a_multiple_private_link": "新增連結",
"multiple_private_link_copied": "私人連結已複製",
"invitees_can_schedule": "受邀者可以預定",
"date_range": "日期範圍",
"calendar_days": "日曆天",
"business_days": "工作天",
"set_address_place": "設定地址或地點",
"set_link_meeting": "設定會議的連結",
"managed_event_field_parent_control_disabled": "無法切換。只能為子事件類型解鎖",
"cal_invitee_phone_number_scheduling": "{{appName}} 會要求受邀者在進行預定之前,輸入電話號碼。",
"cal_provide_google_meet_location": "{{appName}} 會提供 Google Meet 位址。",
"cal_provide_zoom_meeting_url": "{{appName}} 會提供 Zoom 會議網址。",
@@ -1520,6 +1525,7 @@
"workflow_example_4": "在活動開始前 1 小時傳送電子郵件提醒給與會者",
"workflow_example_5": "重新預定活動時傳送自訂電子郵件給主辦者",
"workflow_example_6": "預約新活動時傳送自訂簡訊給主辦者",
"count_managed_to_limit": "包含受管理事件類型的預訂次數",
"welcome_to_cal_header": "歡迎使用 {{appName}}!",
"edit_form_later_subtitle": "您之後可再進行編輯。",
"connect_calendar_later": "我之後再連接行事曆",
@@ -2043,7 +2049,8 @@
"error_charging_card": "收取缺席費時發生問題。請稍後再試一次。",
"collect_no_show_fee": "收取缺席費",
"no_show_fee_charged": "已收取缺席費",
"insights": "Insights",
"insights": "洞察",
"routing_forms": "路由表單",
"testing_workflow_info_message": "測試此工作流程時,請注意電子郵件和簡訊只能提前至少 1 小時預定",
"insights_no_data_found_for_filter": "找不到所選篩選條件或日期的資料。",
"acknowledge_booking_no_show_fee": "我同意若我未出席此活動,將從我的卡片收取 {{amount, currency}} 的缺席費。",
@@ -2107,6 +2114,8 @@
"set_up_your_organization": "設定組織",
"set_up_your_platform_organization": "設置您的平台",
"organizations_description": "組織是一種共用環境,團隊可以在其中建立共用的活動類型、應用程式、工作流程等。",
"platform": "平台",
"platform_description": "管理與平台相關的所有事務。",
"platform_organization_description": "Cal.com 平台讓您可以使用平台 API 和原子輕鬆將排程集成到您的應用中。",
"must_enter_organization_name": "必須輸入組織名稱",
"must_enter_organization_admin_email": "必須輸入組織電子郵件地址",
@@ -2326,6 +2335,7 @@
"unified_billing_description": "添加一張信用卡來支付所有團隊的訂閱費用",
"advanced_managed_events": "高級管理活動類型",
"advanced_managed_events_description": "添加一張信用卡來支付所有團隊的訂閱費用",
"enterprise": "企業",
"enterprise_description": "升級到企業版以創建您的組織",
"create_your_org": "建立你的組織",
"create_your_org_description": "升級到組織版,獲取子域名、統一計費、洞察、廣泛的白標化等功能",
@@ -2612,9 +2622,11 @@
"disable_input_if_prefilled": "如果 URL 識別碼已填寫,則禁用輸入",
"booking_limits": "預約限制",
"booking_limits_team_description": "所有團隊活動類型的團隊成員預約限制",
"limit_team_booking_frequency_description": "限制團隊成員在所有活動類型(集體和round-robin)中的預約次數",
"limit_team_booking_frequency_description": "限制成員在所有團隊事件類型中可被預訂的次數",
"booking_limits_updated_successfully": "預約限制更新成功",
"you_are_unauthorized_to_make_this_change_to_the_booking": "您無權更改此預訂",
"matching_members": "符合條件的成員",
"no_matching_members": "沒有符合條件的成員。將回退使用分配給事件類型的團隊成員。",
"hide_calendar_event_details": "隱藏共享行事曆中的事件詳情",
"description_hide_calendar_event_details": "當行事曆被共享時,事件對讀者可見,但其詳情對沒有寫入權限的人隱藏。",
"last_number_of_days": "過去 {{count}} 天",
+5
View File
@@ -0,0 +1,5 @@
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
});
+5
View File
@@ -0,0 +1,5 @@
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
});
@@ -40,8 +40,6 @@ describe("handleChildrenEventTypes", () => {
children: [],
updatedEventType: { schedulingType: null, slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -64,8 +62,6 @@ describe("handleChildrenEventTypes", () => {
children: [],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -91,8 +87,6 @@ describe("handleChildrenEventTypes", () => {
children: [],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -130,8 +124,6 @@ describe("handleChildrenEventTypes", () => {
children: [{ hidden: false, owner: { id: 4, name: "", email: "", eventTypeSlugs: [] } }],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -184,8 +176,6 @@ describe("handleChildrenEventTypes", () => {
children: [{ hidden: false, owner: { id: 4, name: "", email: "", eventTypeSlugs: [] } }],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: "somestring",
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {
@@ -200,8 +190,10 @@ describe("handleChildrenEventTypes", () => {
scheduleId: null,
lockTimeZoneToggleOnBookingPage: false,
requiresBookerEmailVerification: false,
hashedLink: {
deleteMany: {},
},
instantMeetingScheduleId: undefined,
hashedLink: { create: { link: expect.any(String) } },
},
where: {
userId_parentId: {
@@ -224,8 +216,6 @@ describe("handleChildrenEventTypes", () => {
children: [],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -250,8 +240,6 @@ describe("handleChildrenEventTypes", () => {
],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -290,8 +278,6 @@ describe("handleChildrenEventTypes", () => {
children: [{ hidden: false, owner: { id: 4, name: "", email: "", eventTypeSlugs: ["something"] } }],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -305,12 +291,12 @@ describe("handleChildrenEventTypes", () => {
durationLimits: undefined,
recurringEvent: undefined,
eventTypeColor: undefined,
hashedLink: undefined,
instantMeetingScheduleId: undefined,
lockTimeZoneToggleOnBookingPage: false,
requiresBookerEmailVerification: false,
userId: 4,
workflows: undefined,
hashedLink: undefined,
},
});
expect(result.newUserIds).toEqual([4]);
@@ -345,8 +331,6 @@ describe("handleChildrenEventTypes", () => {
children: [{ hidden: false, owner: { id: 4, name: "", email: "", eventTypeSlugs: ["something"] } }],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {
@@ -358,6 +342,9 @@ describe("handleChildrenEventTypes", () => {
data: {
...rest,
locations: [],
hashedLink: {
deleteMany: {},
},
lockTimeZoneToggleOnBookingPage: false,
requiresBookerEmailVerification: false,
instantMeetingScheduleId: undefined,
@@ -411,8 +398,6 @@ describe("handleChildrenEventTypes", () => {
],
updatedEventType: { schedulingType: "MANAGED", slug: "something" },
currentUserId: 1,
hashedLink: undefined,
connectedLink: null,
prisma: prismaMock,
profileId: null,
updatedValues: {},
@@ -424,7 +409,6 @@ describe("handleChildrenEventTypes", () => {
durationLimits: undefined,
recurringEvent: undefined,
eventTypeColor: undefined,
hashedLink: undefined,
instantMeetingScheduleId: undefined,
locations: [],
lockTimeZoneToggleOnBookingPage: false,
@@ -441,6 +425,7 @@ describe("handleChildrenEventTypes", () => {
workflows: {
create: [{ workflowId: 11 }],
},
hashedLink: undefined,
},
});
const { profileId, ...rest } = evType;
@@ -451,7 +436,9 @@ describe("handleChildrenEventTypes", () => {
locations: [],
lockTimeZoneToggleOnBookingPage: false,
requiresBookerEmailVerification: false,
hashedLink: undefined,
hashedLink: {
deleteMany: {},
},
instantMeetingScheduleId: undefined,
},
where: {
@@ -153,6 +153,7 @@ export type InputEventType = {
users?: { id: number }[];
hosts?: InputHost[];
schedulingType?: SchedulingType;
parent?: { id: number };
beforeEventBuffer?: number;
afterEventBuffer?: number;
teamId?: number | null;
@@ -160,6 +161,7 @@ export type InputEventType = {
id?: number | null;
parentId?: number | null;
bookingLimits?: IntervalLimit;
includeManagedEventsInLimits?: boolean;
};
requiresConfirmation?: boolean;
destinationCalendar?: Prisma.DestinationCalendarCreateInput;
@@ -246,7 +248,7 @@ export async function addEventTypesToDb(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
schedule?: any;
metadata?: any;
team?: { id?: number | null; bookingLimits?: IntervalLimit };
team?: { id?: number | null; bookingLimits?: IntervalLimit; includeManagedEventsInLimits?: boolean };
})[]
) {
log.silly("TestData: Add EventTypes to DB", JSON.stringify(eventTypes));
@@ -292,6 +294,7 @@ export async function addEventTypesToDb(
data: {
id: eventType.team?.id,
bookingLimits: eventType.team?.bookingLimits,
includeManagedEventsInLimits: eventType.team?.includeManagedEventsInLimits,
name: "",
},
});
@@ -323,6 +326,7 @@ export async function addEventTypes(eventTypes: InputEventType[], usersStore: In
beforeEventBuffer: 0,
afterEventBuffer: 0,
bookingLimits: {},
includeManagedEventsInLimits: false,
schedulingType: null,
length: 15,
//TODO: What is the purpose of periodStartDate and periodEndDate? Test these?
@@ -378,6 +382,7 @@ export async function addEventTypes(eventTypes: InputEventType[], usersStore: In
: eventType.schedule,
owner: eventType.owner ? { connect: { id: eventType.owner } } : undefined,
schedulingType: eventType.schedulingType,
parent: eventType.parent ? { connect: { id: eventType.parent.id } } : undefined,
rescheduleWithSameRoundRobinHost: eventType.rescheduleWithSameRoundRobinHost,
};
});
@@ -1285,6 +1290,7 @@ export function getScenarioData(
id: eventType.teamId ?? eventType.team?.id,
parentId: org ? org.id : null,
bookingLimits: eventType?.team?.bookingLimits,
includeManagedEventsInLimits: eventType?.team?.includeManagedEventsInLimits,
},
title: `Test Event Type - ${index + 1}`,
description: `It's a test event type - ${index + 1}`,
+32
View File
@@ -0,0 +1,32 @@
# Mintlify Starter Kit
Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
- Guide pages
- Navigation
- Customizations
- API Reference pages
- Use of popular components
### Development
Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
```
npm i -g mintlify
```
Run the following command at the root of your documentation (where mint.json is)
```
mintlify dev
```
### Publishing Changes
Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
#### Troubleshooting
- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
- Page loads as a 404 - Make sure you are running in a folder with `mint.json`
+17
View File
@@ -0,0 +1,17 @@
---
title: "Authentication"
---
The Cal.com API uses API keys to authenticate requests. You can view and manage your API keys in your settings page under the security tab in Cal.com.
<img src="/images/i1600x899-DllqhV6w_3Vj_oxtjov.png" />
API Keys are under Settings > Security
Test mode secret keys have the prefix `cal_` and live mode secret keys have the prefix `cal_live_`.
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.
Authentication to the API is performed via URL Query Params. Provide your API key as a query param like: `https://api.cal.com/v1/?apiKey=cal_live_xxxxxx`
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
+57
View File
@@ -0,0 +1,57 @@
---
title: "Errors"
---
Cal.com uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, or something else failed, etc.). Codes in the 5xx range indicate an error with Cal.com's servers (these are rare).
<table>
<thead>
<tr>
<th>HTTP</th>
<th>Status Code</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
<tr>
<td>200</td>
<td>OK</td>
<td>Everything worked as expected</td>
</tr>
<tr>
<td>400</td>
<td>Bad Request</td>
<td>The request was unacceptable, often due to missing a required parameter</td>
</tr>
<tr>
<td>401</td>
<td>Unauthorized</td>
<td>No valid API key provided.</td>
</tr>
<tr>
<td>402</td>
<td>Request Failed</td>
<td>The parameters were valid but the request failed.</td>
</tr>
<tr>
<td>403</td>
<td>Forbidden</td>
<td>The API key doesn't have permissions to perform the request.</td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td>The requested resource doesn't exist.</td>
</tr>
<tr>
<td>429</td>
<td>Too Many Requests</td>
<td>Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.</td>
</tr>
<tr>
<td>500, 502, 503, 504</td>
<td>erver Errors</td>
<td>Something went wrong on our servers end. (These are rare.)</td>
</tr>
</tbody>
</table>
+51
View File
@@ -0,0 +1,51 @@
---
title: "Quick start"
---
## Get your API keys
Your API requests are authenticated using API keys. Any request that doesn't include an API key will return an error.
You can generate an API key from **Settings >** [**Security**](https://app.cal.com/settings/security) within the application. There you will find the API keys section which allows you to generate a key for use.
More information on this can be found in the [Authentication](authentication) page.
## Install the library
The best way to interact with our API is using a good HTTP client like **axios**:
<Tabs>
<Tab title="Node">
```
# Install via NPM
npm install --save axios
# Install via Yarn
yarn add axios
```
</Tab>
<Tab title="Python">
```
# Install via pip
pip install --upgrade requests
```
</Tab>
</Tabs>
## Make your first request
To make your first request, send an authenticated request to the event-types endpoint. This will list all of your event types.
Example using `curl`:
<Tabs>
<Tab title="Curl">
```
curl https://api.cal.com/v1/event-types?apiKey=cal_test_xxxxxx
```
</Tab>
</Tabs>
## Try our Postman Collection
We've created a small collection of frequently made API calls that you can try in our [Postman Collection](https://www.postman.com/calcom/workspace/cd670dd8-b36d-4aee-8ab2-9044122e30d1/collection/20666831-b92a1d73-bfcc-4a5f-9ef5-cb117d49c904)
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
---
title: "Rate limits"
---
We limit the number of calls you can make over a certain period of time. Rate limits vary and are specified by the following header in all responses:
<table>
<thead>
<tr>
<th>Header</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>X-RateLimit-Limit</td>
<td>The maximum number of requests that the consumer is permitted to make.</td>
</tr>
<tr>
<td>X-RateLimit-Remaining</td>
<td>The number of requests remaining in the current rate limit window.</td>
</tr>
<tr>
<td>X-RateLimit-Reset</td>
<td>The time at which the current rate limit window resets in UTC epoch seconds.</td>
</tr>
</tbody>
</table>
When the rate limit is **exceeded**, an error is returned with the status **"429 Too Many Requests"**:
```json
{
"error": {
"code": "too_many_requests",
"message": "Rate limit exceeded",
}
}
```
+26
View File
@@ -0,0 +1,26 @@
---
title: 'Introduction to API v2'
description: 'Introduction to Cal.com API v2 endpoints'
---
## Authentication
The Cal.com API uses API keys to authenticate requests. You can view and manage your API keys in your settings page under the security tab in Cal.com.
<img src="/images/i1600x899-DllqhV6w_3Vj_oxtjov.png" />
API Keys are under Settings > Security
Test mode secret keys have the prefix `cal_` and live mode secret keys have the prefix `cal_live_`.
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.
Authentication to the API is performed via the Authorization header. For example, the request would go something like:
```
'Authorization': 'Bearer YOUR_API_KEY'
```
in your request header.
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
---
title: "Differences between v1 and v2"
---
## API Versions
We offer two versions of our API: the legacy version (v1) and the latest v2 version. While both versions are currently available, we highly recommend using the v2 API in all your integrations and applications.
### Why Use v2?
The v2 API includes numerous enhancements and new features that are not available in v1. It has been designed to be more efficient, secure, and easier to use. v2 reflects our commitment to providing the best possible developer experience and ensuring that your applications can take advantage of the latest advancements in our platform.
### Key Differences
- **Performance Improvements**: v2 has been optimized for better performance and scalability.
- **User friendly response objects**: In v2 we have focused heavily on improving the response object for a better User Experience.
- **Enhanced Security**: v2 includes improved security measures to protect your data.
- **Platform product**: Our new Platform product was built entirely on v2.
We are committed to supporting our community during this transition. If you have any questions or need assistance with migrating to the v2 API, please contact our support team.
Thank you for your understanding and cooperation.

Some files were not shown because too many files have changed in this diff Show More