Merge branch 'feat/organizations' into feat/organizations-banner
This commit is contained in:
commit
68b7b7fa9d
|
@ -1,27 +1,75 @@
|
|||
name: "Apply issue labels to PR"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
|
||||
|
||||
jobs:
|
||||
label_on_pr:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
permissions:
|
||||
contents: none
|
||||
issues: read
|
||||
pull-requests: write
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Apply labels from linked issue to PR
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_DATA: ${{ toJson(github.event.pull_request) }}
|
||||
run: node ./.github/workflows/scripts/apply-issue-labels-to-pr.ts
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
async function getLinkedIssues(owner, repo, prNumber) {
|
||||
const query = `query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $prNumber) {
|
||||
closingIssuesReferences(first: 10) {
|
||||
nodes {
|
||||
number
|
||||
labels(first: 10) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const variables = {
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
prNumber: prNumber,
|
||||
};
|
||||
|
||||
const result = await github.graphql(query, variables);
|
||||
return result.repository.pullRequest.closingIssuesReferences.nodes;
|
||||
}
|
||||
|
||||
const pr = context.payload.pull_request;
|
||||
const linkedIssues = await getLinkedIssues(
|
||||
context.repo.owner,
|
||||
context.repo.repo,
|
||||
pr.number
|
||||
);
|
||||
|
||||
const labelsToAdd = new Set();
|
||||
for (const issue of linkedIssues) {
|
||||
if (issue.labels && issue.labels.nodes) {
|
||||
for (const label of issue.labels.nodes) {
|
||||
labelsToAdd.add(label.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (labelsToAdd.size) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: Array.from(labelsToAdd),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
const https = require("https");
|
||||
|
||||
async function applyLabelFromLinkedIssueToPR(pr, token) {
|
||||
// Get the labels from issues linked to the PR
|
||||
const query = `
|
||||
query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $prNumber) {
|
||||
closingIssuesReferences(first: 10) {
|
||||
nodes {
|
||||
number
|
||||
labels(first: 10) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const graphqlData = JSON.stringify({
|
||||
query,
|
||||
variables: {
|
||||
owner: pr.base.repo.owner.login,
|
||||
repo: pr.base.repo.name,
|
||||
prNumber: pr.number,
|
||||
},
|
||||
});
|
||||
|
||||
const requestOptions = {
|
||||
hostname: "api.github.com",
|
||||
path: "/graphql",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Length": graphqlData.length,
|
||||
Authorization: "Bearer " + token,
|
||||
"User-Agent": "Node.js",
|
||||
},
|
||||
};
|
||||
|
||||
// Use the native Node.js request library to make the request
|
||||
let linkedIssues;
|
||||
linkedIssues = await new Promise((resolve, reject) => {
|
||||
const request = https.request(requestOptions, (response) => {
|
||||
let responseBody = "";
|
||||
response.on("data", (chunk) => {
|
||||
responseBody += chunk;
|
||||
});
|
||||
response.on("end", () => {
|
||||
resolve(JSON.parse(responseBody)?.data?.repository?.pullRequest?.closingIssuesReferences?.nodes);
|
||||
});
|
||||
});
|
||||
|
||||
request.on("error", (error) => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
request.write(graphqlData);
|
||||
request.end();
|
||||
});
|
||||
|
||||
if (!linkedIssues || linkedIssues.length === 0) {
|
||||
console.log("No issue linked.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over linked issues and apply labels to PR
|
||||
for (const issue of linkedIssues) {
|
||||
const labels = issue?.labels?.nodes?.map((label) => label.name);
|
||||
|
||||
if (!labels || labels.length === 0) {
|
||||
console.log(`No labels found on the linked issue #${issue.number}.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const labelsData = JSON.stringify({
|
||||
labels: labels,
|
||||
});
|
||||
|
||||
const requestOptions = {
|
||||
hostname: "api.github.com",
|
||||
path: `/repos/${pr.base.repo.owner.login}/${pr.base.repo.name}/issues/${pr.number}/labels`,
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Length": labelsData.length,
|
||||
Authorization: "Bearer " + token,
|
||||
"User-Agent": "Node.js",
|
||||
},
|
||||
};
|
||||
|
||||
let labelResult;
|
||||
labelResult = await new Promise((resolve, reject) => {
|
||||
const request = https.request(requestOptions, (response) => {
|
||||
let responseBody = "";
|
||||
response.on("data", (chunk) => {
|
||||
responseBody += chunk;
|
||||
});
|
||||
response.on("data", () => {});
|
||||
response.on("end", () => {
|
||||
resolve(JSON.parse(responseBody));
|
||||
});
|
||||
});
|
||||
|
||||
request.on("error", (error) => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
request.write(labelsData);
|
||||
request.end();
|
||||
});
|
||||
|
||||
if (labelResult.message) {
|
||||
console.log(`Error labelling PR: ${labelResult.message}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Applied labels: ${labels.join(", ")} to PR #${pr.number} from linked issue #${issue.number}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass the PR data and GitHub token to the script
|
||||
(async () => {
|
||||
if (!process.env.PR_DATA) {
|
||||
console.log("No PR data found.");
|
||||
return;
|
||||
}
|
||||
|
||||
const prData = JSON.parse(process.env.PR_DATA);
|
||||
const token = process.env.GITHUB_TOKEN;
|
||||
|
||||
await applyLabelFromLinkedIssueToPR(prData, token);
|
||||
})();
|
|
@ -133,7 +133,12 @@ async function handler(req: NextApiRequest) {
|
|||
});
|
||||
if (!team) throw new HttpError({ statusCode: 404, message: "teamId not found" });
|
||||
if (!team.members) throw new HttpError({ statusCode: 404, message: "team has no members" });
|
||||
const allMemberIds = team.members.map((membership) => membership.userId);
|
||||
const allMemberIds = team.members.reduce((allMemberIds: number[], member) => {
|
||||
if (member.accepted) {
|
||||
allMemberIds.push(member.userId);
|
||||
}
|
||||
return allMemberIds;
|
||||
}, []);
|
||||
const members = await prisma.user.findMany({
|
||||
where: { id: { in: allMemberIds } },
|
||||
select: availabilityUserSelect,
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
import { createContext } from "@calcom/trpc/server/createContext";
|
||||
import { viewerRouter } from "@calcom/trpc/server/routers/viewer/_router";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
/** @see https://trpc.io/docs/server-side-calls */
|
||||
const ctx = await createContext({ req, res });
|
||||
const caller = viewerRouter.createCaller(ctx);
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return await caller.slots.getSchedule(req.query as any /* Let tRPC handle this */);
|
||||
} catch (cause) {
|
||||
if (cause instanceof TRPCError) {
|
||||
const statusCode = getHTTPStatusCodeFromError(cause);
|
||||
throw new HttpError({ statusCode, message: cause.message });
|
||||
}
|
||||
throw cause;
|
||||
}
|
||||
}
|
||||
|
||||
export default defaultResponder(handler);
|
|
@ -0,0 +1,9 @@
|
|||
import { defaultHandler } from "@calcom/lib/server";
|
||||
|
||||
import { withMiddleware } from "~/lib/helpers/withMiddleware";
|
||||
|
||||
export default withMiddleware()(
|
||||
defaultHandler({
|
||||
GET: import("./_get"),
|
||||
})
|
||||
);
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "2.9.4",
|
||||
"version": "2.9.5.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
"rejection_confirmation": "رفض الحجز",
|
||||
"manage_this_event": "قم بإدارة هذا الحدث",
|
||||
"invite_team_member": "دعوة عضو في الفريق",
|
||||
"invite_team_individual_segment": "دعوة فرد",
|
||||
"invite_team_bulk_segment": "استيراد بحجم جماعي",
|
||||
"invite_team_notifcation_badge": "دعوة",
|
||||
"your_event_has_been_scheduled": "تم جدولة الحدث الخاص بك",
|
||||
"your_event_has_been_scheduled_recurring": "تم جدولة الحدث المتكرر الخاص بك",
|
||||
|
@ -222,6 +224,7 @@
|
|||
"go_back_login": "العودة إلى صفحة تسجيل الدخول",
|
||||
"error_during_login": "حدث خطأ ما أثناء تسجيل الدخول. ارجع إلى شاشة تسجيل الدخول وحاول مجددًا.",
|
||||
"request_password_reset": "إرسال بريد إلكتروني لإعادة التعيين",
|
||||
"send_invite": "إرسال دعوة",
|
||||
"forgot_password": "هل نسيت كلمة المرور؟",
|
||||
"forgot": "هل نسيت؟",
|
||||
"done": "تم",
|
||||
|
@ -237,6 +240,8 @@
|
|||
"set_availability": "تحديد الوقت الذي تكون فيه متاحًا",
|
||||
"continue_without_calendar": "المتابعة من دون تقويم",
|
||||
"connect_your_calendar": "ربط التقويم لديك",
|
||||
"connect_your_video_app": "اربط تطبيقاتك الفيديو الخاصة بك",
|
||||
"connect_your_video_app_instructions": "قم بتوصيل تطبيقات الفيديو لديك لاستخدامها في أنواع الأحداث الخاصة بك.",
|
||||
"connect_your_calendar_instructions": "اربط التقويم لديك للتحقق تلقائيًا من الأوقات المشغولة والأحداث الجديدة أثناء جدولتها.",
|
||||
"set_up_later": "الإعداد لاحقًا",
|
||||
"current_time": "الوقت الحالي",
|
||||
|
@ -366,6 +371,7 @@
|
|||
"create_webhook": "إنشاء الويب هوك",
|
||||
"booking_cancelled": "تم إلغاء الحجز",
|
||||
"booking_rescheduled": "تمت إعادة جدولة الحجز",
|
||||
"recording_ready": "رابط تنزيل التسجيل جاهز",
|
||||
"booking_created": "تم إنشاء الحجز",
|
||||
"meeting_ended": "انتهى الاجتماع",
|
||||
"form_submitted": "تم إرسال النموذج",
|
||||
|
@ -464,6 +470,7 @@
|
|||
"friday": "الجمعة",
|
||||
"saturday": "السبت",
|
||||
"sunday": "الأحد",
|
||||
"all_booked_today": "تم حجز الكل.",
|
||||
"slots_load_fail": "تعذر تحميل الفترات الزمنية المتاحة.",
|
||||
"additional_guests": "إضافة ضيوف",
|
||||
"your_name": "اسمك",
|
||||
|
@ -751,6 +758,10 @@
|
|||
"new_event_type_to_book_description": "قم بإنشاء نوع حدث جديد ليحجز الأشخاص من خلاله.",
|
||||
"length": "الطول",
|
||||
"minimum_booking_notice": "الحد الأدنى من الوقت للحجز",
|
||||
"offset_toggle": "أوقات بدء الإزاحة",
|
||||
"offset_toggle_description": "إزاحة الفتحات الزمنية المعروضة للحاجزين بعدد محدد من الدقائق",
|
||||
"offset_start": "إزاحة بمقدار",
|
||||
"offset_start_description": "على سبيل المثال، هذا سيُظهر فتحات زمنية لمن يقوم بالحجز لديك {{ adjustedTime }} بدلاً من {{ originalTime }}",
|
||||
"slot_interval": "الفترات الزمنية بين عمليات الحجز",
|
||||
"slot_interval_default": "استخدام طول الحدث (الوضع الافتراضي)",
|
||||
"delete_event_type": "هل تريد حذف نوع الحدث؟",
|
||||
|
@ -903,6 +914,7 @@
|
|||
"duplicate": "تكرار",
|
||||
"offer_seats": "عرض مقاعد",
|
||||
"offer_seats_description": "عرض مقاعد للحجز. هذا يعطل تلقائياً حجز الضيوف وحجز الاشتراك.",
|
||||
"seats_available_one": "المقاعد المتاحة",
|
||||
"seats_available_other": "المقاعد المتاحة",
|
||||
"number_of_seats": "عدد المقاعد لكل حجز",
|
||||
"enter_number_of_seats": "أدخل عدد المقاعد",
|
||||
|
@ -1037,6 +1049,7 @@
|
|||
"event_cancelled_trigger": "متى تم إلغاء هذا الحدث",
|
||||
"new_event_trigger": "متى تم حجز الحدث الجديد",
|
||||
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
|
||||
"email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور",
|
||||
"sms_attendee_action": "إرسال رسالة نصية قصيرة إلى واحد من الحضور",
|
||||
"sms_number_action": "إرسال رسالة نصية قصيرة إلى رقم محدد",
|
||||
"workflows": "سير العمل",
|
||||
|
@ -1189,6 +1202,7 @@
|
|||
"create_workflow": "إنشاء سير عمل",
|
||||
"do_this": "افعل هذا",
|
||||
"turn_off": "إيقاف التشغيل",
|
||||
"turn_on": "تشغيل",
|
||||
"settings_updated_successfully": "تم تحديث الإعدادات بنجاح",
|
||||
"error_updating_settings": "خطأ في تحديث الإعدادات",
|
||||
"personal_cal_url": "عنوان {{appName}} URL الخاص بي",
|
||||
|
@ -1245,6 +1259,7 @@
|
|||
"calendars_description": "قم بتهيئة كيفية تفاعل أنواع الأحداث مع التقويمات الخاصة بك",
|
||||
"appearance_description": "إدارة إعدادات مظهر الحجز الخاص بك",
|
||||
"conferencing_description": "أضف تطبيقات مؤتمرات الفيديو المفضلة لديك لاجتماعاتك",
|
||||
"add_conferencing_app": "إضافة تطبيق عقد اجتماعات",
|
||||
"password_description": "إدارة إعدادات كلمات مرور حسابك",
|
||||
"2fa_description": "إدارة إعدادات كلمات مرور حسابك",
|
||||
"we_just_need_basic_info": "نحتاج إلى بعض المعلومات الأساسية لإعداد ملفك الشخصي.",
|
||||
|
@ -1325,7 +1340,6 @@
|
|||
"exchange_version_2013_SP1": "2013 SP1",
|
||||
"exchange_version_2015": "2015",
|
||||
"exchange_version_2016": "2016",
|
||||
"routing_forms_description": "يمكنك رؤية جميع النماذج والتوجيهات التي أنشأتها هنا.",
|
||||
"routing_forms_send_email_owner": "إرسال رسالة إلكترونية إلى المالك",
|
||||
"routing_forms_send_email_owner_description": "يرسل رسالة بريد إلكتروني إلى المالك عند إرسال النموذج",
|
||||
"add_new_form": "إضافة استمارة جديدة",
|
||||
|
@ -1619,6 +1633,7 @@
|
|||
"email_user_cta": "عرض الدعوة",
|
||||
"email_no_user_invite_heading": "لقد تمت دعوتك للانضمام إلى فريق في {{appName}}",
|
||||
"email_no_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
|
||||
"email_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه {{teamName}} على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
|
||||
"email_no_user_invite_steps_intro": "سنرشدك خلال بضع خطوات قصيرة وستستمتع بجدولة خالية من الإجهاد مع فريقك وسريعة.",
|
||||
"email_no_user_step_one": "اختر اسم المستخدم الخاص بك",
|
||||
"email_no_user_step_two": "ربط حساب التقويم الخاص بك",
|
||||
|
@ -1694,6 +1709,15 @@
|
|||
"spot_popular_event_types_description": "تعرف أي أنواع من الأحداث لديك تتلقى أكبر عدد من النقرات والحجوزات",
|
||||
"no_responses_yet": "لا توجد ردود بعد",
|
||||
"this_will_be_the_placeholder": "سيكون هذا هو العنصر النائب",
|
||||
"error_booking_event": "حدث خطأ عند حجز الحدث، الرجاء تحديث الصفحة والمحاولة ثانيةً",
|
||||
"timeslot_missing_title": "لم يتم تحديد مساحة زمنية",
|
||||
"timeslot_missing_description": "الرجاء تحديد فترة زمنية لحجز الحدث.",
|
||||
"timeslot_missing_cta": "حدد الوقت",
|
||||
"switch_monthly": "التبديل إلى العرض الشهري",
|
||||
"switch_weekly": "التبديل إلى العرض الأسبوعي",
|
||||
"switch_multiday": "التبديل إلى العرض اليومي",
|
||||
"num_locations": "خيارات الموقع {{num}}",
|
||||
"select_on_next_step": "حدد في الخطوة التالية",
|
||||
"this_meeting_has_not_started_yet": "لم يبدأ هذا الاجتماع بعد",
|
||||
"this_app_requires_connected_account": "{{appName}} يتطلب حساب {{dependencyName}} متصل",
|
||||
"connect_app": "اتصال {{dependencyName}}",
|
||||
|
@ -1723,6 +1747,7 @@
|
|||
"locked_apps_description": "سيتمكن الأعضاء من رؤية التطبيقات النشطة، ولكن لن يتمكنوا من تعديل أي إعدادات للتطبيق",
|
||||
"locked_webhooks_description": "سيكون الأعضاء قادرين على رؤية webhooks النشطة، ولكن من دون القدرة على تعديل أي إعدادات Webhook",
|
||||
"locked_workflows_description": "سيكون الأعضاء قادرين على رؤية مسارات العمل النشطة، ولكن من دون القدرة على تعديل أي إعدادات لمسار العمل",
|
||||
"locked_by_admin": "مقفل من قبل المشرف",
|
||||
"app_not_connected": "أنت غير متصل بحساب {{appName}}.",
|
||||
"connect_now": "اتصل الآن",
|
||||
"managed_event_dialog_confirm_button_one": "الاستبدال وإخطار {{count}} عضو",
|
||||
|
@ -1780,5 +1805,21 @@
|
|||
"seats_and_no_show_fee_error": "لا يمكن حاليًا تمكين المقاعد وفرض رسوم عدم الحضور",
|
||||
"complete_your_booking": "أكمل الحجز",
|
||||
"complete_your_booking_subject": "أكمل الحجز: {{title}} في {{date}}",
|
||||
"email_invite_team": "تم دعوة {{email}}"
|
||||
"confirm_your_details": "تأكيد التفاصيل الخاصة بك",
|
||||
"currency_string": "{{amount, currency}}",
|
||||
"charge_card_dialog_body": "أنت على وشك استحصال مبلغ {{amount, currency}} من أحد الحضور. هل أنت متأكد من أنك تريد المتابعة؟",
|
||||
"charge_attendee": "استحصال مبلغ {{amount, currency}} من أحد الحضور",
|
||||
"payment_app_commission": "يتطلب الدفع ({{paymentFeePercentage}}% + {{fee, currency}} عمولة لكل معاملة)",
|
||||
"email_invite_team": "تم دعوة {{email}}",
|
||||
"email_invite_team_bulk": "{{userCount}} مستخدم تم دعوتهم",
|
||||
"error_collecting_card": "خطأ في تحصيل البطاقة",
|
||||
"image_size_limit_exceed": "لا ينبغي أن تتجاوز الصورة التي تم تحميلها الحد الأقصى لحجم 5 ميغابايت",
|
||||
"inline_embed": "Inline Embed",
|
||||
"load_inline_content": "يحمّل نوع الحدث الخاص بك مباشرة مع محتوى موقعك الأخير.",
|
||||
"floating_pop_up_button": "زر منبثق عائم",
|
||||
"floating_button_trigger_modal": "يضع زرًا عائمًا على موقعك يقوم بتشغيل توجيه مع نوع الحدث الخاص بك.",
|
||||
"pop_up_element_click": "ينبثق عبر النقر على العنصر",
|
||||
"open_dialog_with_element_click": "افتح مربع الحوار الخاص بك عندما ينقر شخص على عنصر ما.",
|
||||
"need_help_embedding": "بحاجة إلى مساعدة؟ راجع أدلتنا لإدراج Cal على Wix، Squarespace، أو WordPress، تحقق من أسئلتنا المشتركة، أو استكشف خيارات متقدمة متضمنة.",
|
||||
"book_my_cal": "ثبّت الحجز في رزنامتي"
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
"rejection_confirmation": "Odmítnout rezervaci",
|
||||
"manage_this_event": "Spravovat tuto událost",
|
||||
"invite_team_member": "Pozvat člena týmu",
|
||||
"invite_team_individual_segment": "Pozvat jednotlivce",
|
||||
"invite_team_bulk_segment": "Hromadný import",
|
||||
"invite_team_notifcation_badge": "Pozv.",
|
||||
"your_event_has_been_scheduled": "Vaše událost byla naplánována",
|
||||
"your_event_has_been_scheduled_recurring": "Opakovaná událost byla naplánována",
|
||||
|
@ -222,6 +224,7 @@
|
|||
"go_back_login": "Zpět na přihlašovací stránku",
|
||||
"error_during_login": "Při přihlašování došlo k chybě. Přejděte zpět na přihlašovací obrazovku a zkuste to znovu.",
|
||||
"request_password_reset": "Žádost o obnovení hesla",
|
||||
"send_invite": "Odeslat pozvánku",
|
||||
"forgot_password": "Zapomenuté heslo",
|
||||
"forgot": "Zapomněli jste?",
|
||||
"done": "Hotovo",
|
||||
|
@ -237,6 +240,8 @@
|
|||
"set_availability": "Nastavte, jak jste dostupní",
|
||||
"continue_without_calendar": "Pokračovat bez kalendáře",
|
||||
"connect_your_calendar": "Připojit svůj kalendář",
|
||||
"connect_your_video_app": "Propojte své video aplikace",
|
||||
"connect_your_video_app_instructions": "Propojte své video aplikace a používejte je v typech událostí.",
|
||||
"connect_your_calendar_instructions": "Připojit kalendář pro automatickou kontrolu časů, kdy nejste dostupní, a nově naplánovaných událostí.",
|
||||
"set_up_later": "Zprovoznit později",
|
||||
"current_time": "Aktuální čas",
|
||||
|
@ -366,6 +371,7 @@
|
|||
"create_webhook": "Vytvořit webhook",
|
||||
"booking_cancelled": "Rezervace zrušena",
|
||||
"booking_rescheduled": "Rezervace přesunuta",
|
||||
"recording_ready": "Odkaz ke stažení záznamu je připraven",
|
||||
"booking_created": "Rezervace vytvořena",
|
||||
"meeting_ended": "Schůzka skončila",
|
||||
"form_submitted": "Formulář byl odeslán",
|
||||
|
@ -464,6 +470,7 @@
|
|||
"friday": "pátek",
|
||||
"saturday": "sobota",
|
||||
"sunday": "neděle",
|
||||
"all_booked_today": "Vše zarezervováno.",
|
||||
"slots_load_fail": "Nepodařilo se načíst dostupné časové sloty.",
|
||||
"additional_guests": "Přidat hosty",
|
||||
"your_name": "Vaše jméno",
|
||||
|
@ -751,6 +758,10 @@
|
|||
"new_event_type_to_book_description": "Vytvořit nový typ události, ve které si lidé mohou rezervovat časy.",
|
||||
"length": "Doba trvání",
|
||||
"minimum_booking_notice": "Minimální potřebná doba",
|
||||
"offset_toggle": "Posunutí časů začátku",
|
||||
"offset_toggle_description": "Posunutí časových slotů zobrazených rezervujícím osobám o zadaný počet minut",
|
||||
"offset_start": "Posunutí o",
|
||||
"offset_start_description": "například v tomto případě se vašim rezervujícím zobrazí časové sloty v {{ adjustedTime }} namísto {{ originalTime }}",
|
||||
"slot_interval": "Časové intervaly",
|
||||
"slot_interval_default": "Použít délku události (výchozí)",
|
||||
"delete_event_type": "Odstranit typ události?",
|
||||
|
@ -903,6 +914,7 @@
|
|||
"duplicate": "Duplikovat",
|
||||
"offer_seats": "Nabídka míst",
|
||||
"offer_seats_description": "Nabídnout místa k rezervaci. Tím se vypnou rezervace hostů a volitelné rezervace.",
|
||||
"seats_available_one": "Dostupné místo",
|
||||
"seats_available_other": "Dostupná místa",
|
||||
"number_of_seats": "Počet míst na rezervaci",
|
||||
"enter_number_of_seats": "Zadejte počet míst",
|
||||
|
@ -1037,6 +1049,7 @@
|
|||
"event_cancelled_trigger": "při zrušení události",
|
||||
"new_event_trigger": "při rezervaci nové události",
|
||||
"email_host_action": "odeslání e-mailu hostiteli",
|
||||
"email_attendee_action": "odeslat e-mail účastníkům",
|
||||
"sms_attendee_action": "odeslání SMS účastníkovi",
|
||||
"sms_number_action": "odeslání SMS na konkrétní číslo",
|
||||
"workflows": "Pracovní postupy",
|
||||
|
@ -1189,6 +1202,7 @@
|
|||
"create_workflow": "Vytvoření pracovního postupu",
|
||||
"do_this": "Provést",
|
||||
"turn_off": "Vypnout",
|
||||
"turn_on": "Zapnout",
|
||||
"settings_updated_successfully": "Nastavení aktualizováno",
|
||||
"error_updating_settings": "Chyba při aktualizaci nastavení",
|
||||
"personal_cal_url": "Moje osobní adresa URL {{appName}}",
|
||||
|
@ -1245,6 +1259,7 @@
|
|||
"calendars_description": "Konfigurace způsobu interakce typů událostí s kalendáři",
|
||||
"appearance_description": "Správa nastavení vzhledu rezervace",
|
||||
"conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky",
|
||||
"add_conferencing_app": "Přidat videokonferenční aplikaci",
|
||||
"password_description": "Správa nastavení hesel k vašemu účtu",
|
||||
"2fa_description": "Správa nastavení hesel k vašemu účtu",
|
||||
"we_just_need_basic_info": "K nastavení vašeho profilu potřebujeme jen několik základních informací.",
|
||||
|
@ -1619,6 +1634,7 @@
|
|||
"email_user_cta": "Zobrazit pozvánku",
|
||||
"email_no_user_invite_heading": "Byli jste pozváni do týmu v aplikaci {{appName}}",
|
||||
"email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.",
|
||||
"email_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu „{{teamName}}“ v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového pingpongu.",
|
||||
"email_no_user_invite_steps_intro": "Provedeme vás několika krátkými kroky a za malou chvíli si budete se svým týmem užívat plánování bez stresu.",
|
||||
"email_no_user_step_one": "Vyberte si uživatelské jméno",
|
||||
"email_no_user_step_two": "Připojte svůj účet kalendáře",
|
||||
|
@ -1694,6 +1710,15 @@
|
|||
"spot_popular_event_types_description": "Zjistěte, které typy vašich událostí získávají nejvíce kliknutí a rezervací",
|
||||
"no_responses_yet": "Zatím žádné odpovědi",
|
||||
"this_will_be_the_placeholder": "Toto bude zástupný znak",
|
||||
"error_booking_event": "Při rezervaci události došlo k chybě, obnovte prosím stránku a zkuste to znovu",
|
||||
"timeslot_missing_title": "Nebyl vybrán žádný časový slot",
|
||||
"timeslot_missing_description": "Vyberte časový slot, aby mohla být událost zaregistrována.",
|
||||
"timeslot_missing_cta": "Vybrat časový slot",
|
||||
"switch_monthly": "Přepnout na měsíční zobrazení",
|
||||
"switch_weekly": "Přepnout na týdenní zobrazení",
|
||||
"switch_multiday": "Přepnout na denní zobrazení",
|
||||
"num_locations": "Možná místa konání: {{num}}",
|
||||
"select_on_next_step": "Vyberte v dalším kroku",
|
||||
"this_meeting_has_not_started_yet": "Tato schůzka ještě nezačala",
|
||||
"this_app_requires_connected_account": "{{appName}} vyžaduje připojený účet {{dependencyName}}",
|
||||
"connect_app": "Připojit aplikaci {{dependencyName}}",
|
||||
|
@ -1723,6 +1748,7 @@
|
|||
"locked_apps_description": "Členové uvidí aktivní aplikace, ale nastavení aplikací upravovat nemohou",
|
||||
"locked_webhooks_description": "Členové uvidí aktivní webhooky, ale nastavení webhooků upravovat nemohou",
|
||||
"locked_workflows_description": "Členové uvidí aktivní pracovní postupy, ale nastavení pracovních postupů upravovat nemohou",
|
||||
"locked_by_admin": "Uzamčeno správcem týmu",
|
||||
"app_not_connected": "Nemáte připojený účet {{appName}}.",
|
||||
"connect_now": "Připojte se",
|
||||
"managed_event_dialog_confirm_button_one": "Nahradit a upozornit {{count}} člena",
|
||||
|
@ -1780,5 +1806,34 @@
|
|||
"seats_and_no_show_fee_error": "V současné době nelze povolit místa a strhnout poplatek za nedostavení se",
|
||||
"complete_your_booking": "Dokončete svou rezervaci",
|
||||
"complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}",
|
||||
"email_invite_team": "Pozvánka pro uživatele {{email}} odeslána"
|
||||
"confirm_your_details": "Potvrďte své údaje",
|
||||
"currency_string": "{{amount, currency}}",
|
||||
"charge_card_dialog_body": "Chystáte se účtovat účastníkovi {{amount, currency}}. Opravdu chcete pokračovat?",
|
||||
"charge_attendee": "Naúčtovat účastníkovi {{amount, currency}}",
|
||||
"payment_app_commission": "Vyžadujte platbu ({{paymentFeePercentage}} % + provizi {{fee, currency}} za transakci)",
|
||||
"email_invite_team": "Pozvánka pro uživatele {{email}} odeslána",
|
||||
"email_invite_team_bulk": "Počet pozvaných uživatelů: {{userCount}}",
|
||||
"error_collecting_card": "Chyba při výběru karty",
|
||||
"image_size_limit_exceed": "Velikost nahraného obrázku by neměla překročit limit 5 MB",
|
||||
"inline_embed": "Embed inline",
|
||||
"load_inline_content": "Načte váš typ události přímo „inline“ s ostatním obsahem webu.",
|
||||
"floating_pop_up_button": "Plovoucí překryvné tlačítko",
|
||||
"floating_button_trigger_modal": "Umístí na váš web plovoucí tlačítko, které spustí modální okno s vaším typem události.",
|
||||
"pop_up_element_click": "Překryvné okno při kliknutí na prvek",
|
||||
"open_dialog_with_element_click": "Otevře dialogové okno Cal, pokud někdo klikne na prvek.",
|
||||
"need_help_embedding": "Potřebujete pomoc? Prohlédněte si naše průvodce pro vložení Cal do Wixu, Squarespace nebo WordPressu, podívejte se na naše nejčastější dotazy nebo prozkoumejte pokročilé možnosti vložení.",
|
||||
"book_my_cal": "Book my Cal",
|
||||
"invite_as": "Pozvat jako",
|
||||
"form_updated_successfully": "Formulář byl aktualizován.",
|
||||
"email_not_cal_member_cta": "Připojte se ke svému týmu",
|
||||
"disable_attendees_confirmation_emails": "Vypnutí výchozích potvrzovacích e-mailů pro účastníky",
|
||||
"disable_attendees_confirmation_emails_description": "U tohoto typu události je aktivní alespoň jeden pracovní postup, který po rezervaci události odešle účastníkům e-mail.",
|
||||
"disable_host_confirmation_emails": "Vypnutí výchozích potvrzovacích e-mailů pro hostitele",
|
||||
"disable_host_confirmation_emails_description": "U tohoto typu události je aktivní alespoň jeden pracovní postup, který po rezervaci události odešle hostiteli e-mail.",
|
||||
"add_an_override": "Přidejte změnu",
|
||||
"import_from_google_workspace": "Importovat uživatele z Google Workspace",
|
||||
"connect_google_workspace": "Propojit s Google Workspace",
|
||||
"google_workspace_admin_tooltip": "Používání této funkce vyžaduje, abyste byli administrátory Google Workspace",
|
||||
"first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události",
|
||||
"create_for": "Vytvořit pro"
|
||||
}
|
||||
|
|
|
@ -1281,7 +1281,6 @@
|
|||
"exchange_authentication_standard": "Grundlæggende autentificering",
|
||||
"exchange_authentication_ntlm": "NTLM autentificering",
|
||||
"exchange_compression": "GZip komprimering",
|
||||
"routing_forms_description": "Du kan se alle former og ruter du har oprettet her.",
|
||||
"routing_forms_send_email_owner": "Send e-mail til Ejer",
|
||||
"routing_forms_send_email_owner_description": "Sender en e-mail til ejeren når formularen er indsendt",
|
||||
"add_new_form": "Tilføj ny formular",
|
||||
|
|
|
@ -222,6 +222,7 @@
|
|||
"go_back_login": "Zurück zur Login-Seite",
|
||||
"error_during_login": "Beim Anmelden ist ein Fehler aufgetreten. Gehen Sie zurück zum Anmeldebildschirm und versuchen Sie es erneut.",
|
||||
"request_password_reset": "Passwort zurücksetzen",
|
||||
"send_invite": "Einladung senden",
|
||||
"forgot_password": "Passwort vergessen",
|
||||
"forgot": "Vergessen?",
|
||||
"done": "Erledigt",
|
||||
|
@ -237,6 +238,7 @@
|
|||
"set_availability": "Verfügbarkeit festlegen",
|
||||
"continue_without_calendar": "Ohne Kalender fortfahren",
|
||||
"connect_your_calendar": "Kalender verbinden",
|
||||
"connect_your_video_app": "Verbinden Sie Ihre Video-Apps",
|
||||
"connect_your_calendar_instructions": "Verbinden Sie Ihren Kalender, um automatisch zu prüfen, ob Termine verfügbar sind.",
|
||||
"set_up_later": "Später einrichten",
|
||||
"current_time": "Aktuelle Zeit",
|
||||
|
@ -464,6 +466,7 @@
|
|||
"friday": "Freitag",
|
||||
"saturday": "Samstag",
|
||||
"sunday": "Sonntag",
|
||||
"all_booked_today": "Alle gebucht.",
|
||||
"slots_load_fail": "Die verfügbaren Zeitfenster konnten nicht geladen werden.",
|
||||
"additional_guests": "+ Weitere Gäste",
|
||||
"your_name": "Ihr Name",
|
||||
|
@ -1694,6 +1697,7 @@
|
|||
"spot_popular_event_types_description": "Sehen Sie, welche Ihrer Ereignistypen die meisten Klicks und Buchungen erhalten",
|
||||
"no_responses_yet": "Noch keine Antworten",
|
||||
"this_will_be_the_placeholder": "Dies wird der Platzhalter sein",
|
||||
"switch_monthly": "Zur monatlichen Ansicht wechseln",
|
||||
"this_meeting_has_not_started_yet": "Dieses Meeting hat noch nicht begonnen",
|
||||
"this_app_requires_connected_account": "{{appName}} benötigt ein verbundenes {{dependencyName}}-Konto",
|
||||
"connect_app": "{{dependencyName}} verbinden",
|
||||
|
@ -1734,7 +1738,7 @@
|
|||
"managed_event_dialog_clarification": "Wenn Sie die URL ersetzen, werden wir sie benachrichtigen. Gehen Sie zurück und entfernen Sie sie, wenn Sie sie nicht überschreiben möchten.",
|
||||
"review_event_type": "Ereignistyp überprüfen",
|
||||
"looking_for_more_analytics": "Suchen Sie nach weiteren Analysedaten?",
|
||||
"looking_for_more_insights": "Suchen Sie nach weiteren Einsichten?",
|
||||
"looking_for_more_insights": "Möchten Sie mehr Insights?",
|
||||
"add_filter": "Filter hinzufügen",
|
||||
"select_user": "Benutzer auswählen",
|
||||
"select_event_type": "Ereignistyp auswählen",
|
||||
|
|
|
@ -1843,5 +1843,6 @@
|
|||
"create_for": "Create for",
|
||||
"setup_organisation": "Setup an Organization",
|
||||
"organisation_banner_description": "Create an environments where your teams can create shared apps, workflows and event types with round-robin and collective scheduling.",
|
||||
"organisation_banner_title": "Manage organizations with multiple teams"
|
||||
"organisation_banner_title": "Manage organizations with multiple teams",
|
||||
"additional_url_parameters":"Additional URL parameters"
|
||||
}
|
||||
|
|
|
@ -1634,7 +1634,7 @@
|
|||
"email_user_cta": "Visualizza invito",
|
||||
"email_no_user_invite_heading": "Sei stato invitato a unirti a un team su {{appName}}",
|
||||
"email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
|
||||
"email_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
|
||||
"email_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette a te e al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
|
||||
"email_no_user_invite_steps_intro": "Ti assisteremo nei passaggi iniziali in modo che tu possa pianificare eventi per il tuo team senza stress e in pochissimo tempo.",
|
||||
"email_no_user_step_one": "Scegli il tuo nome utente",
|
||||
"email_no_user_step_two": "Collega il tuo account di calendario",
|
||||
|
@ -1760,7 +1760,7 @@
|
|||
"managed_event_dialog_clarification": "Se decidi di sostituirlo, i membri ne saranno avvisati. Torna indietro e rimuovili se non desideri sovrascriverlo.",
|
||||
"review_event_type": "Rivedi tipo di evento",
|
||||
"looking_for_more_analytics": "Hai bisogno di più dati analitici?",
|
||||
"looking_for_more_insights": "Hai bisogno di maggiori approfondimenti?",
|
||||
"looking_for_more_insights": "Ti servono più Insights?",
|
||||
"add_filter": "Aggiungi filtro",
|
||||
"select_user": "Seleziona utente",
|
||||
"select_event_type": "Seleziona tipo di evento",
|
||||
|
@ -1821,7 +1821,7 @@
|
|||
"floating_button_trigger_modal": "Inserisce nel sito un pulsante mobile che attiva una finestra modale con il tuo tipo di evento.",
|
||||
"pop_up_element_click": "Finestra popup tramite clic su un elemento",
|
||||
"open_dialog_with_element_click": "Apre la finestra di dialogo di Cal quando un utente clicca su un elemento.",
|
||||
"need_help_embedding": "Hai bisogno di aiuto? Consulta le nostre guide per integrare Cal su Wix, Squarespace o WordPress, legge le risposte alle domande più frequenti o esplora le opzioni di icorporamento avanzate.",
|
||||
"need_help_embedding": "Hai bisogno di aiuto? Consulta le nostre guide per integrare Cal su Wix, Squarespace o WordPress, leggi le risposte alle domande più frequenti o esplora le opzioni di incorporamento avanzate.",
|
||||
"book_my_cal": "Prenota il mio Cal",
|
||||
"invite_as": "Invita come",
|
||||
"form_updated_successfully": "Modulo aggiornato correttamente.",
|
||||
|
|
|
@ -1258,7 +1258,6 @@
|
|||
"exchange_authentication_standard": "Enkel autentisering",
|
||||
"exchange_authentication_ntlm": "NTLM autentisering",
|
||||
"exchange_compression": "GZip komprimering",
|
||||
"routing_forms_description": "Du kan se alle skjemaer og viderekoblinger du har laget her.",
|
||||
"routing_forms_send_email_owner": "Send E-post til Eier",
|
||||
"routing_forms_send_email_owner_description": "Sender en e-post til eieren når skjemaet er sendt inn",
|
||||
"add_new_form": "Legg til nytt skjema",
|
||||
|
|
|
@ -761,7 +761,7 @@
|
|||
"offset_toggle": "Deslocar horas de início",
|
||||
"offset_toggle_description": "Desloca na quantidade de minutos especificada as alocações de tempo mostradas aos reservantes",
|
||||
"offset_start": "Deslocar em",
|
||||
"offset_start_description": "ex.: serão mostrados espaços de tempo aos seus reservantes à(s) {{ adjustedTime }} em vez de {{ originalTime }}",
|
||||
"offset_start_description": "ex.: serão mostradas alocações de tempo aos seus reservantes à(s) {{ adjustedTime }} em vez de {{ originalTime }}",
|
||||
"slot_interval": "Intervalos de tempo",
|
||||
"slot_interval_default": "Usar a duração do evento (padrão)",
|
||||
"delete_event_type": "Excluir tipo de evento?",
|
||||
|
@ -1340,7 +1340,7 @@
|
|||
"exchange_version_2013_SP1": "2013 SP1",
|
||||
"exchange_version_2015": "2015",
|
||||
"exchange_version_2016": "2016",
|
||||
"routing_forms_description": "Você pode ver todos os formulários e rotas que criou aqui",
|
||||
"routing_forms_description": "Criar formulários para direcionar os participantes para os destinos corretos",
|
||||
"routing_forms_send_email_owner": "Enviar e-mail ao proprietário",
|
||||
"routing_forms_send_email_owner_description": "Envia um e-mail ao proprietário após o envio do formulário",
|
||||
"add_new_form": "Adicionar novo formulário",
|
||||
|
|
|
@ -1340,7 +1340,6 @@
|
|||
"exchange_version_2013_SP1": "2013 SP1",
|
||||
"exchange_version_2015": "2015",
|
||||
"exchange_version_2016": "2016",
|
||||
"routing_forms_description": "Aqui pode ver todos os formulários e rotas que criou.",
|
||||
"routing_forms_send_email_owner": "Enviar e-mail ao proprietário",
|
||||
"routing_forms_send_email_owner_description": "Envia um e-mail ao proprietário quando o formulário for submetido",
|
||||
"add_new_form": "Adicionar novo formulário",
|
||||
|
|
|
@ -195,6 +195,7 @@
|
|||
"page_doesnt_exist": "Ova stranica ne postoji.",
|
||||
"check_spelling_mistakes_or_go_back": "Proverite greške u pisanju ili idite nazad na prethodnu stranicu.",
|
||||
"404_page_not_found": "404: Ovu stranicu ne možemo da nadjemo.",
|
||||
"booker_event_not_found": "Nismo mogli da pronađemo događaj koji pokušavate da zakažete.",
|
||||
"getting_started": "Započnite",
|
||||
"15min_meeting": "Sastanak od 15 Min",
|
||||
"30min_meeting": "Sastanak od 30 Min",
|
||||
|
@ -363,6 +364,7 @@
|
|||
"user_dynamic_booking_disabled": "Neki od korisnika u ovoj grupi trenutno su onemogućili dinamičke grupne rezervacije",
|
||||
"allow_dynamic_booking_tooltip": "Moguće je dinamičko kreiranje linkova za grupne rezervacije navođenjem više korisničkih imena sa znakom „+”. Na primer: „{{appName}}/bailey+peer”",
|
||||
"allow_dynamic_booking": "Dozvolite učesnicima da rezervišu termin sa vama putem dinamičkih grupnih rezervacija",
|
||||
"dynamic_booking": "Dinamični linkovi grupa",
|
||||
"email": "E-pošta",
|
||||
"email_placeholder": "ppetrovic@example.com",
|
||||
"full_name": "Ime i prezime",
|
||||
|
@ -373,6 +375,8 @@
|
|||
"booking_rescheduled": "Rezervacija Odložena",
|
||||
"recording_ready": "Link za preuzimanje snimka je spreman",
|
||||
"booking_created": "Rezervacija Napravljena",
|
||||
"booking_rejected": "Rezevacija je odbijena",
|
||||
"booking_requested": "Rezervacija je zahtevana",
|
||||
"meeting_ended": "Sastanak se završio",
|
||||
"form_submitted": "Formular poslat",
|
||||
"event_triggers": "Okidači Dogadjaja",
|
||||
|
@ -1815,6 +1819,7 @@
|
|||
"email_invite_team_bulk": "Pozvano je {{userCount}} korisnika",
|
||||
"error_collecting_card": "Greška u sakupljanju kartice",
|
||||
"image_size_limit_exceed": "Otpremljena slika ne sme da prevazilazi ograničenje od 5mb",
|
||||
"unauthorized_workflow_error_message": "{{errorCode}}: Niste ovlašćeni da omogućite ili onemogućite ovaj radni tok",
|
||||
"inline_embed": "Ugradi neposredno",
|
||||
"load_inline_content": "Direktno učitava vaš tip događaja neposredno sa vašim ostalim sadržajem na veb sajtu.",
|
||||
"floating_pop_up_button": "Plutajuće iskačuće dugme",
|
||||
|
|
|
@ -760,6 +760,7 @@
|
|||
"minimum_booking_notice": "Minimum Bildirim",
|
||||
"offset_toggle": "Ofset başlangıç saatleri",
|
||||
"offset_toggle_description": "Belirli bir dakika sayısına göre rezervasyon yapanlara gösterilen ofset zaman aralıkları",
|
||||
"offset_start": "Ofset",
|
||||
"offset_start_description": "örneğin; bu işlem rezervasyon yapan kişinin zaman aralıklarını {{ originalTime }} yerine {{ adjustedTime }} olarak görmesine neden olur",
|
||||
"slot_interval": "Zaman dilimi aralıkları",
|
||||
"slot_interval_default": "Etkinlik uzunluğunu kullan (varsayılan)",
|
||||
|
@ -1759,7 +1760,7 @@
|
|||
"managed_event_dialog_clarification": "Değiştirmeyi seçmeniz durumunda kullanıcıları bilgilendireceğiz. Üzerine yazmak istemiyorsanız geri dönerek onları kaldırın.",
|
||||
"review_event_type": "Etkinlik Türünü inceleyin",
|
||||
"looking_for_more_analytics": "Daha fazla analiz mi arıyorsunuz?",
|
||||
"looking_for_more_insights": "Daha fazla Öngörü mü arıyorsunuz?",
|
||||
"looking_for_more_insights": "Daha fazla Insights mı arıyorsunuz?",
|
||||
"add_filter": "Filtre ekle",
|
||||
"select_user": "Kullanıcı seç",
|
||||
"select_event_type": "Etkinlik Türü seç",
|
||||
|
@ -1812,15 +1813,27 @@
|
|||
"payment_app_commission": "Ödeme talep edin (işlem başına %{{paymentFeePercentage}} + {{fee, currency}} komisyon)",
|
||||
"email_invite_team": "{{email}} davet edildi",
|
||||
"email_invite_team_bulk": "{{userCount}} kullanıcı davet edildi",
|
||||
"error_collecting_card": "Kart bilgileri alınırken hata oluştu",
|
||||
"image_size_limit_exceed": "Yüklenen resim boyutu 5 MB boyut sınırını aşmamalıdır",
|
||||
"inline_embed": "Satır İçine Yerleştir",
|
||||
"load_inline_content": "Etkinlik türünüzü doğrudan diğer web sitesi içeriğinizle birlikte yükler.",
|
||||
"floating_pop_up_button": "Kayan açılır düğme",
|
||||
"floating_button_trigger_modal": "Sitenize, bir olay türüne sahip bir modu tetikleyen kayan bir düğme ekler.",
|
||||
"pop_up_element_click": "Ögenin tıklanmasıyla açılır",
|
||||
"open_dialog_with_element_click": "Birisi bir öğeyi tıkladığında Cal iletişim kutunuzu açın.",
|
||||
"need_help_embedding": "Yardıma mı ihtiyacınız var? Cal'ı Wix, Squarespace veya WordPress'e yerleştirmek için kılavuzlarımıza göz atın. Ayrıca Sıkça Sorulan Sorular bölümümüze göz atın veya gelişmiş yerleştirme seçeneklerini keşfedin.",
|
||||
"book_my_cal": "Cal'ımı rezerve et",
|
||||
"invite_as": "Davet edin",
|
||||
"form_updated_successfully": "Form başarıyla güncellendi.",
|
||||
"email_not_cal_member_cta": "Ekibinize ekleyin",
|
||||
"disable_attendees_confirmation_emails": "Katılımcılar için varsayılan onay e-postalarını devre dışı bırakın",
|
||||
"disable_attendees_confirmation_emails_description": "Bu etkinlik türünde etkinlik rezerve edildiğinde katılımcılara bir e-posta gönderen en az bir iş akışı etkin.",
|
||||
"disable_host_confirmation_emails": "Organizatörler için varsayılan onay e-postalarını devre dışı bırakın",
|
||||
"disable_host_confirmation_emails_description": "Bu etkinlik türündeki bir etkinlik rezerve edildiğinde organizatörlere e-posta gönderen en az bir iş akışı etkin.",
|
||||
"add_an_override": "Üzerine yazma ekle",
|
||||
"import_from_google_workspace": "Kullanıcıları, Google Workspace'ten içe aktarın",
|
||||
"connect_google_workspace": "Google Workspace'i bağlayın",
|
||||
"google_workspace_admin_tooltip": "Bu özelliği kullanmak için Çalışma Alanı Yöneticisi olmalısınız",
|
||||
"first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun"
|
||||
"first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun",
|
||||
"create_for": "Oluşturun"
|
||||
}
|
||||
|
|
|
@ -1760,7 +1760,7 @@
|
|||
"managed_event_dialog_clarification": "Якщо ви захочете замінити її, ми повідомимо учасників. Поверніться і вилучіть їх, замість того щоб перезаписувати.",
|
||||
"review_event_type": "Переглянути тип заходу",
|
||||
"looking_for_more_analytics": "Потрібно більше аналітичних даних?",
|
||||
"looking_for_more_insights": "Потрібно більше аналітики?",
|
||||
"looking_for_more_insights": "Потрібно більше висновків Insights?",
|
||||
"add_filter": "Додати фільтр",
|
||||
"select_user": "Вибрати користувача",
|
||||
"select_event_type": "Вибрати тип заходу",
|
||||
|
|
|
@ -1340,7 +1340,7 @@
|
|||
"exchange_version_2013_SP1": "2013 SP1",
|
||||
"exchange_version_2015": "2015",
|
||||
"exchange_version_2016": "2016",
|
||||
"routing_forms_description": "创建表格以将参与者引导到正确的目的地",
|
||||
"routing_forms_description": "创建表格以将参与者引导到正确的目标",
|
||||
"routing_forms_send_email_owner": "向所有者发送电子邮件",
|
||||
"routing_forms_send_email_owner_description": "提交表单后向所有者发送电子邮件",
|
||||
"add_new_form": "添加新表格",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import type { PartialReference } from "@calcom/types/EventManager";
|
||||
import type { VideoApiAdapter, VideoCallData } from "@calcom/types/VideoApiAdapter";
|
||||
|
||||
|
@ -11,19 +12,28 @@ const JitsiVideoApiAdapter = (): VideoApiAdapter => {
|
|||
getAvailability: () => {
|
||||
return Promise.resolve([]);
|
||||
},
|
||||
createMeeting: async (): Promise<VideoCallData> => {
|
||||
createMeeting: async (eventData: CalendarEvent): Promise<VideoCallData> => {
|
||||
const appKeys = await getAppKeysFromSlug(metadata.slug);
|
||||
|
||||
const meetingID = uuidv4();
|
||||
const meetingPattern = (appKeys.jitsiPathPattern as string) || "{uuid}";
|
||||
const hostUrl = (appKeys.jitsiHost as string) || "https://meet.jit.si/cal";
|
||||
|
||||
// Default Value
|
||||
const hostUrl = appKeys.jitsiHost || "https://meet.jit.si/cal";
|
||||
//Allows "/{Type}-with-{Attendees}" slug
|
||||
const meetingID = meetingPattern
|
||||
.replaceAll("{uuid}", uuidv4())
|
||||
.replaceAll("{Title}", eventData.title)
|
||||
.replaceAll("{Event Type Title}", eventData.type)
|
||||
.replaceAll("{Scheduler}", eventData.attendees.map((a) => a.name).join("-"))
|
||||
.replaceAll("{Organizer}", eventData.organizer.name)
|
||||
.replaceAll("{Location}", eventData.location || "")
|
||||
.replaceAll("{Team}", eventData.team?.name || "")
|
||||
.replaceAll(" ", "-"); //Last Rule! - Replace all blanks (%20) with dashes;
|
||||
|
||||
return Promise.resolve({
|
||||
type: metadata.type,
|
||||
id: meetingID,
|
||||
password: "",
|
||||
url: hostUrl + "/" + meetingID,
|
||||
url: hostUrl + "/" + encodeURIComponent(meetingID),
|
||||
});
|
||||
},
|
||||
deleteMeeting: async (): Promise<void> => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { z } from "zod";
|
|||
|
||||
export const appKeysSchema = z.object({
|
||||
jitsiHost: z.string().optional(),
|
||||
jitsiPathPattern: z.string().optional(),
|
||||
});
|
||||
|
||||
export const appDataSchema = z.object({});
|
||||
|
|
|
@ -3,15 +3,19 @@ import { useState } from "react";
|
|||
import { useAppContextWithSchema } from "@calcom/app-store/EventTypeAppContext";
|
||||
import AppCard from "@calcom/app-store/_components/AppCard";
|
||||
import type { EventTypeAppCardComponent } from "@calcom/app-store/types";
|
||||
import { Tooltip } from "@calcom/ui";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Tooltip, TextField } from "@calcom/ui";
|
||||
|
||||
import type { appDataSchema } from "../zod";
|
||||
|
||||
const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({ eventType, app }) {
|
||||
const { t } = useLocale();
|
||||
const [getAppData, setAppData] = useAppContextWithSchema<typeof appDataSchema>();
|
||||
const [enabled, setEnabled] = useState(getAppData("enabled"));
|
||||
const [additionalParameters, setAdditionalParameters] = useState("");
|
||||
|
||||
const eventTypeURL = eventType.URL;
|
||||
const query = additionalParameters !== "" ? `?${additionalParameters}` : "";
|
||||
const eventTypeURL = eventType.URL + query;
|
||||
|
||||
function QRCode({ size, data }: { size: number; data: string }) {
|
||||
const QR_URL = "https://api.qrserver.com/v1/create-qr-code/?size=" + size + "&data=" + data;
|
||||
|
@ -19,7 +23,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
|||
<Tooltip content={eventTypeURL}>
|
||||
<a download href={QR_URL} target="_blank" rel="noreferrer">
|
||||
<img
|
||||
className="hover:bg-muted border hover:shadow-sm"
|
||||
className="hover:bg-muted border-default border hover:shadow-sm"
|
||||
style={{ padding: size / 16, borderRadius: size / 20 }}
|
||||
width={size}
|
||||
src={QR_URL}
|
||||
|
@ -42,10 +46,22 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
|||
}
|
||||
}}
|
||||
switchChecked={enabled}>
|
||||
<div className="max-w-60 flex items-baseline justify-between gap-2 text-sm ">
|
||||
<QRCode size={256} data={eventTypeURL} />
|
||||
<QRCode size={128} data={eventTypeURL} />
|
||||
<QRCode size={64} data={eventTypeURL} />
|
||||
<div className="flex w-full flex-col gap-2 text-sm">
|
||||
<div className="flex w-full">
|
||||
<TextField
|
||||
name="hello"
|
||||
value={additionalParameters}
|
||||
onChange={(e) => setAdditionalParameters(e.target.value)}
|
||||
label={t("additional_url_parameters")}
|
||||
containerClassName="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="max-w-60 flex items-baseline gap-2">
|
||||
<QRCode size={256} data={eventTypeURL} />
|
||||
<QRCode size={128} data={eventTypeURL} />
|
||||
<QRCode size={64} data={eventTypeURL} />
|
||||
</div>
|
||||
</div>
|
||||
</AppCard>
|
||||
);
|
||||
|
|
|
@ -103,7 +103,7 @@ const BookerComponent = ({
|
|||
since that's not a valid option, so it would set the layout to null.
|
||||
*/}
|
||||
{!isMobile && (
|
||||
<div className="[&>div]:bg-default fixed top-2 right-3 z-10">
|
||||
<div className="[&>div]:bg-default dark:[&>div]:bg-muted fixed top-2 right-3 z-10">
|
||||
<ToggleGroup
|
||||
onValueChange={onLayoutToggle}
|
||||
defaultValue={layout}
|
||||
|
@ -133,7 +133,7 @@ const BookerComponent = ({
|
|||
className={classNames(
|
||||
// Sets booker size css variables for the size of all the columns.
|
||||
...getBookerSizeClassNames(layout, bookerState),
|
||||
"bg-default grid max-w-full auto-rows-fr items-start overflow-clip dark:[color-scheme:dark] sm:transition-[width] sm:duration-300 sm:motion-reduce:transition-none md:flex-row",
|
||||
"bg-default dark:bg-muted grid max-w-full auto-rows-fr items-start overflow-clip dark:[color-scheme:dark] sm:transition-[width] sm:duration-300 sm:motion-reduce:transition-none md:flex-row",
|
||||
layout === "small_calendar" && "border-subtle rounded-md border"
|
||||
)}>
|
||||
<AnimatePresence>
|
||||
|
|
|
@ -20,7 +20,7 @@ export function BookFormAsModal({ visible, onCancel }: { visible: boolean; onCan
|
|||
<DialogContent
|
||||
type={undefined}
|
||||
enableOverflow
|
||||
className="[&_.modalsticky]:border-t-subtle [&_.modalsticky]:bg-default max-h-[80vh] pt-6 pb-0 [&_.modalsticky]:sticky [&_.modalsticky]:bottom-0 [&_.modalsticky]:left-0 [&_.modalsticky]:right-0 [&_.modalsticky]:-mx-8 [&_.modalsticky]:border-t [&_.modalsticky]:px-6 [&_.modalsticky]:py-4">
|
||||
className="[&_.modalsticky]:border-t-subtle [&_.modalsticky]:bg-default dark:[&_.modalsticky]:bg-muted max-h-[80vh] pt-6 pb-0 [&_.modalsticky]:sticky [&_.modalsticky]:bottom-0 [&_.modalsticky]:left-0 [&_.modalsticky]:right-0 [&_.modalsticky]:-mx-8 [&_.modalsticky]:border-t [&_.modalsticky]:px-6 [&_.modalsticky]:py-4">
|
||||
<h1 className="font-cal text-emphasis text-xl leading-5">{t("confirm_your_details")} </h1>
|
||||
<div className="mt-4 flex space-x-2 rounded-md leading-none">
|
||||
<Badge variant="grayWithoutHover" startIcon={Calendar} size="lg">
|
||||
|
|
|
@ -11,7 +11,7 @@ export const LargeCalendar = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<div className="bg-default flex h-full w-full flex-col items-center justify-center">
|
||||
<div className="bg-default dark:bg-muted flex h-full w-full flex-col items-center justify-center">
|
||||
Something big is coming...
|
||||
<br />
|
||||
<button
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|||
|
||||
const UnAvailableMessage = ({ children, title }: { children: React.ReactNode; title: string }) => (
|
||||
<div className="mx-auto w-full max-w-2xl">
|
||||
<div className="border-subtle bg-default overflow-hidden rounded-lg border p-10">
|
||||
<div className="border-subtle bg-default dark:bg-muted overflow-hidden rounded-lg border p-10">
|
||||
<h2 className="font-cal mb-4 text-3xl">{title}</h2>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@ export const AvailableTimes = ({
|
|||
|
||||
return (
|
||||
<div className={classNames("text-default", className)}>
|
||||
<header className="bg-muted before:bg-muted mb-5 flex w-full flex-row items-center font-medium">
|
||||
<header className="bg-default before:bg-default dark:bg-muted dark:before:bg-muted mb-5 flex w-full flex-row items-center font-medium">
|
||||
<span className={classNames(isLargeTimeslots && "w-full text-center")}>
|
||||
<span className="text-emphasis font-semibold">
|
||||
{nameOfDay(i18n.language, Number(date.format("d")), "short")}
|
||||
|
|
|
@ -489,7 +489,6 @@ function getBookingData({
|
|||
}
|
||||
}
|
||||
});
|
||||
debugger;
|
||||
const reqBody = bookingDataSchema.parse(req.body);
|
||||
if ("customInputs" in reqBody) {
|
||||
if (reqBody.customInputs) {
|
||||
|
@ -585,7 +584,6 @@ async function handler(
|
|||
...eventType,
|
||||
bookingFields: getBookingFieldsWithSystemFields(eventType),
|
||||
};
|
||||
debugger;
|
||||
const {
|
||||
recurringCount,
|
||||
allRecurringDates,
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
import { Suspense } from "react";
|
||||
|
||||
import NoSSR from "@calcom/core/components/NoSSR";
|
||||
import { Meta } from "@calcom/ui";
|
||||
import { Loader } from "@calcom/ui/components/icon";
|
||||
import { Meta, SkeletonText, SkeletonContainer } from "@calcom/ui";
|
||||
|
||||
import { FlagAdminList } from "../components/FlagAdminList";
|
||||
|
||||
const SkeletonLoader = () => {
|
||||
return (
|
||||
<SkeletonContainer>
|
||||
<div className="divide-subtle mt-6 mb-8 space-y-6">
|
||||
<SkeletonText className="h-8 w-full" />
|
||||
<SkeletonText className="h-8 w-full" />
|
||||
</div>
|
||||
</SkeletonContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export const FlagListingView = () => {
|
||||
return (
|
||||
<>
|
||||
<Meta title="Feature Flags" description="Here you can toggle your Cal.com instance features." />
|
||||
<NoSSR>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<Suspense fallback={<SkeletonLoader />}>
|
||||
<FlagAdminList />
|
||||
</Suspense>
|
||||
</NoSSR>
|
||||
|
|
|
@ -29,7 +29,7 @@ export const DateSelect = () => {
|
|||
range &&
|
||||
(range === "tdy" || range === "w" || range === "t" || range === "m" || range === "y")
|
||||
) {
|
||||
setDateRange([dayjs(start), dayjs(end), range]);
|
||||
setDateRange([dayjs(start).startOf("d"), dayjs(end).endOf("d"), range]);
|
||||
return;
|
||||
} else if (start && !end) {
|
||||
// If only start time has value that means selected date should push to dateRange with last value null
|
||||
|
|
|
@ -5,7 +5,7 @@ import Link from "next/link";
|
|||
import type { NextRouter } from "next/router";
|
||||
import { useRouter } from "next/router";
|
||||
import type { Dispatch, ReactNode, SetStateAction } from "react";
|
||||
import React, { Fragment, useEffect, useState, useRef, useLayoutEffect } from "react";
|
||||
import React, { Fragment, useEffect, useState, useRef } from "react";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
|
@ -21,6 +21,7 @@ import AdminPasswordBanner from "@calcom/features/users/components/AdminPassword
|
|||
import classNames from "@calcom/lib/classNames";
|
||||
import { APP_NAME, DESKTOP_APP_LINK, JOIN_SLACK, ROADMAP, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import getBrandColours from "@calcom/lib/getBrandColours";
|
||||
import { useIsomorphicLayoutEffect } from "@calcom/lib/hooks/useIsomorphicLayoutEffect";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { isKeyInObject } from "@calcom/lib/isKeyInObject";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
|
@ -143,7 +144,7 @@ const Layout = (props: LayoutProps) => {
|
|||
const bannerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [bannersHeight, setBannersHeight] = useState<number>(0);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
const { offsetHeight } = entries[0].target as HTMLElement;
|
||||
setBannersHeight(offsetHeight);
|
||||
|
@ -641,34 +642,34 @@ const NavigationItem: React.FC<{
|
|||
return (
|
||||
<Fragment>
|
||||
<Tooltip side="right" content={t(item.name)} className="lg:hidden">
|
||||
<Link
|
||||
href={item.href}
|
||||
aria-label={t(item.name)}
|
||||
className={classNames(
|
||||
"hover:bg-emphasis [&[aria-current='page']]:bg-emphasis hover:text-emphasis text-default group flex items-center rounded-md py-2 px-3 text-sm font-medium",
|
||||
isChild
|
||||
? `[&[aria-current='page']]:text-emphasis hidden h-8 pl-16 lg:flex lg:pl-11 [&[aria-current='page']]:bg-transparent ${
|
||||
props.index === 0 ? "mt-0" : "mt-px"
|
||||
}`
|
||||
: "[&[aria-current='page']]:text-emphasis mt-0.5 text-sm"
|
||||
)}
|
||||
aria-current={current ? "page" : undefined}>
|
||||
{item.icon && (
|
||||
<item.icon
|
||||
className="h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2 [&[aria-current='page']]:text-inherit"
|
||||
aria-hidden="true"
|
||||
aria-current={current ? "page" : undefined}
|
||||
/>
|
||||
)}
|
||||
{isLocaleReady ? (
|
||||
<span className="hidden w-full justify-between lg:flex">
|
||||
<div className="flex">{t(item.name)}</div>
|
||||
{item.badge && item.badge}
|
||||
</span>
|
||||
) : (
|
||||
<SkeletonText className="h-3 w-32" />
|
||||
)}
|
||||
</Link>
|
||||
<Link
|
||||
href={item.href}
|
||||
aria-label={t(item.name)}
|
||||
className={classNames(
|
||||
"hover:bg-emphasis [&[aria-current='page']]:bg-emphasis hover:text-emphasis text-default group flex items-center rounded-md py-2 px-3 text-sm font-medium",
|
||||
isChild
|
||||
? `[&[aria-current='page']]:text-emphasis hidden h-8 pl-16 lg:flex lg:pl-11 [&[aria-current='page']]:bg-transparent ${
|
||||
props.index === 0 ? "mt-0" : "mt-px"
|
||||
}`
|
||||
: "[&[aria-current='page']]:text-emphasis mt-0.5 text-sm"
|
||||
)}
|
||||
aria-current={current ? "page" : undefined}>
|
||||
{item.icon && (
|
||||
<item.icon
|
||||
className="h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2 [&[aria-current='page']]:text-inherit"
|
||||
aria-hidden="true"
|
||||
aria-current={current ? "page" : undefined}
|
||||
/>
|
||||
)}
|
||||
{isLocaleReady ? (
|
||||
<span className="hidden w-full justify-between lg:flex">
|
||||
<div className="flex">{t(item.name)}</div>
|
||||
{item.badge && item.badge}
|
||||
</span>
|
||||
) : (
|
||||
<SkeletonText className="h-3 w-32" />
|
||||
)}
|
||||
</Link>
|
||||
</Tooltip>
|
||||
{item.child &&
|
||||
isCurrent({ router, isChild, item }) &&
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import { useEffect, useLayoutEffect } from "react";
|
||||
|
||||
export const useIsomorphicLayoutEffect = typeof document !== "undefined" ? useLayoutEffect : useEffect;
|
|
@ -5,6 +5,7 @@ import type { NextApiResponse, GetServerSidePropsContext } from "next";
|
|||
import { stripeDataSchema } from "@calcom/app-store/stripepayment/lib/server";
|
||||
import updateChildrenEventTypes from "@calcom/features/ee/managed-event-types/lib/handleChildrenEventTypes";
|
||||
import { validateIntervalLimitOrder } from "@calcom/lib";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { WorkflowActions, WorkflowTriggerEvents } from "@calcom/prisma/client";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
|
||||
|
@ -287,7 +288,12 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
|||
});
|
||||
const res = ctx.res as NextApiResponse;
|
||||
if (typeof res?.revalidate !== "undefined") {
|
||||
await res?.revalidate(`/${ctx.user.username}/${eventType.slug}`);
|
||||
try {
|
||||
await res?.revalidate(`/${ctx.user.username}/${eventType.slug}`);
|
||||
} catch (e) {
|
||||
// if reach this it is because the event type page has not been created, so it is not possible to revalidate it
|
||||
logger.debug((e as Error)?.message);
|
||||
}
|
||||
}
|
||||
return { eventType };
|
||||
};
|
||||
|
|
|
@ -7,13 +7,13 @@ export const getScheduleSchema = z
|
|||
// endTime ISOString
|
||||
endTime: z.string(),
|
||||
// Event type ID
|
||||
eventTypeId: z.number().int().optional(),
|
||||
eventTypeId: z.coerce.number().int().optional(),
|
||||
// Event type slug
|
||||
eventTypeSlug: z.string(),
|
||||
eventTypeSlug: z.string().optional(),
|
||||
// invitee timezone
|
||||
timeZone: z.string().optional(),
|
||||
// or list of users (for dynamic events)
|
||||
usernameList: z.array(z.string()).optional(),
|
||||
usernameList: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
debug: z.boolean().optional(),
|
||||
// to handle event types with multiple duration options
|
||||
duration: z
|
||||
|
@ -21,9 +21,16 @@ export const getScheduleSchema = z
|
|||
.optional()
|
||||
.transform((val) => val && parseInt(val)),
|
||||
})
|
||||
.transform((val) => {
|
||||
// Need this so we can pass a single username in the query string form public API
|
||||
if (val.usernameList) {
|
||||
val.usernameList = Array.isArray(val.usernameList) ? val.usernameList : [val.usernameList];
|
||||
}
|
||||
return val;
|
||||
})
|
||||
.refine(
|
||||
(data) => !!data.eventTypeId || !!data.usernameList,
|
||||
"Either usernameList or eventTypeId should be filled in."
|
||||
(data) => !!data.eventTypeId || (!!data.usernameList && !!data.eventTypeSlug),
|
||||
"You need to either pass an eventTypeId OR an usernameList/eventTypeSlug combination"
|
||||
);
|
||||
|
||||
export const reserveSlotSchema = z
|
||||
|
|
|
@ -11,8 +11,7 @@ import isTimeOutOfBounds from "@calcom/lib/isOutOfBounds";
|
|||
import logger from "@calcom/lib/logger";
|
||||
import { performance } from "@calcom/lib/server/perfObserver";
|
||||
import getTimeSlots from "@calcom/lib/slots";
|
||||
import { availabilityUserSelect } from "@calcom/prisma";
|
||||
import prisma from "@calcom/prisma";
|
||||
import prisma, { availabilityUserSelect } from "@calcom/prisma";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
import type { EventBusyDate } from "@calcom/types/Calendar";
|
||||
|
@ -140,6 +139,12 @@ export async function getEventType(input: TGetScheduleInputSchema) {
|
|||
|
||||
export async function getDynamicEventType(input: TGetScheduleInputSchema) {
|
||||
// For dynamic booking, we need to get and update user credentials, schedule and availability in the eventTypeObject as they're required in the new availability logic
|
||||
if (!input.eventTypeSlug) {
|
||||
throw new TRPCError({
|
||||
message: "eventTypeSlug is required for dynamic booking",
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
const dynamicEventType = getDefaultEvent(input.eventTypeSlug);
|
||||
const users = await prisma.user.findMany({
|
||||
where: {
|
||||
|
|
|
@ -30,7 +30,7 @@ const ColorPicker = (props: ColorPickerProps) => {
|
|||
return (
|
||||
<div className="mt-1 flex h-[38px] items-center justify-center">
|
||||
<Popover.Root>
|
||||
<div className="border-default flex h-full w-10 items-center items-center justify-center border ltr:rounded-l-md ltr:border-r-0 rtl:rounded-r-md rtl:border-l-0">
|
||||
<div className="border-default min-w-9 flex h-full items-center justify-center border ltr:rounded-l-md ltr:border-r-0 rtl:rounded-r-md rtl:border-l-0">
|
||||
<Popover.Trigger asChild>
|
||||
<button
|
||||
className="h-5 w-5 rounded-sm"
|
||||
|
|
|
@ -30,7 +30,9 @@ function BasePhoneInput({ name, className = "", onChange, ...rest }: PhoneInputP
|
|||
required: rest.required,
|
||||
placeholder: rest.placeholder,
|
||||
}}
|
||||
onChange={(value) => onChange(value)}
|
||||
onChange={(value) => {
|
||||
onChange("+" + value);
|
||||
}}
|
||||
containerClass={classNames(
|
||||
"hover:border-emphasis dark:focus:border-emphasis border-default !bg-default rounded-md border focus-within:outline-none focus-within:ring-2 focus-within:ring-brand-default disabled:cursor-not-allowed",
|
||||
className
|
||||
|
@ -63,7 +65,7 @@ const useDefaultCountry = () => {
|
|||
retry: false,
|
||||
onSuccess: (data) => {
|
||||
if (isSupportedCountry(data?.countryCode)) {
|
||||
setDefaultCountry(data.countryCode);
|
||||
setDefaultCountry(data.countryCode.toLowerCase());
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user