Merged main

This commit is contained in:
Jeroen Reumkens 2023-01-30 08:57:59 -05:00
parent 73f4e48ee5
commit dce6ebd79a
90 changed files with 298 additions and 279 deletions

View File

@ -34,7 +34,6 @@
<a href="https://jitsu.com?utm_source=github/calcom/cal.com"><img src="https://img.shields.io/badge/Metrics_tracked_by-JITSU-AA00FF?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACKSURBVHgBrZDRCYAwDEQv6gCOoKO4hOCXI9QVnEZwiY5iF5GaVClaBNtioCSUvCR3tMJaxIfZgW4AGUoEPVwgPZoS0Dmgg3NBVDFNbMIsmYCak3J1jDk9iCQvsKJvkzr71N81Gj6vDT/LU2P6RhY63jcafk3YJEbgeZpiFyc/5HJKv8Ef273NSfABGbQfUZhnOSAAAAAASUVORK5CYII=" alt="Jitsu Tracked"></a>
<img src="https://api.checklyhq.com/v1/badges/checks/5e048048-1b51-47ba-9209-60607507622e?responseTime=true" alt="Checkly Availability" />
<a href="https://hub.docker.com/r/calendso/calendso"><img src="https://img.shields.io/docker/pulls/calendso/calendso"></a>
<a href="https://twitter.com/calcom"><img src="https://img.shields.io/twitter/follow/calcom?style=flat"></a>
<a href="https://twitch.tv/calcomtv"><img src="https://img.shields.io/twitch/status/calcomtv?style=flat"></a>
<a href="https://github.com/calcom/cal.com/issues?q=is:issue+is:open+label:%22%F0%9F%99%8B%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8Fhelp+wanted%22"><img src="https://img.shields.io/badge/Help%20Wanted-Contribute-blue"></a>
<a href="https://cal.com/figma"><img src="https://img.shields.io/badge/Figma-Design%20System-blueviolet"></a>
@ -85,10 +84,11 @@ That's where Cal.com comes in. Self-hosted or hosted by us. White-label by desig
### Built With
- [Next.js](https://nextjs.org/)
- [React](https://reactjs.org/)
- [Tailwind](https://tailwindcss.com/)
- [Prisma](https://prisma.io/)
- [Next.js](https://nextjs.org/?ref=cal.com)
- [tRPC](https://trpc.io/?ref=cal.com)
- [React](https://reactjs.org/?ref=cal.com)
- [Tailwind](https://tailwindcss.com/?ref=cal.com)
- [Prisma](https://prisma.io/?ref=cal.com)
## Stay Up-to-Date

View File

@ -1,81 +1 @@
<!-- PROJECT LOGO -->
<div align="right">
<a href="https://github.com/calcom/cal.com">
<img src="https://user-images.githubusercontent.com/8019099/133430653-24422d2a-3c8d-4052-9ad6-0580597151ee.png" alt="Logo">
</a>
<a href="https://cal.com">Website</a>
·
<a href="https://github.com/calcom/cal.com/issues">Community Support</a>
</div>
# Cal.com Documentation
The official product, support and developer documentation, containing information and guides about using the product as well as support for self-hosted installations. This documentation site runs on [Nextra](https://nextra.vercel.app), so you may refer to their documentation should you need information on anything that isn't covered here.
## Prerequisites
- Git
- Node.js & npm
- Yarn
## Installation
Firstly, clone the repository using Git:
```console
git clone https://github.com/calcom/docs.git
```
Now, you can install the dependencies with yarn:
```console
yarn install
```
## Editing
To create, edit and delete documentation pages, you can simply create markdown (.mdx) files in the `pages/` folder. You can edit Markdown with any text editor, but VS Code and WebStorm have side-by-side previews so you can see your formatted content whilst writing markdown.
You will also need to add it as an entry to the `meta.json` file found in whichever directory that the .mdx file is in.
## Local Development
```console
yarn dev
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
yarn build
```
This command generates static content into the `build` directory and can be served using any static content hosting service.
## How to easily contribute
## Existing Page
1. From the documentation's GitHub repository, head to the folder called 'pages' and open it.
2. From here you can view all current pages on the documentation site. Select the page you would like to contribute to.
3. You should now be able to view the page you have selected. Located at the top right of the page will be a pencil icon. Pressing this will bring you up an editor to edit and make changes. You can add formatting using the buttons at the top, which will automatically insert the relevant markdown content needed to style the text.
4. From here make the changes you wish to make.
5. At the bottom of the screen will be a 'Propose Changes' box, fill in all the relevant details such as title and description then press the green 'Propose Changes' button.
6. Your changes have been saved, to submit them for review, located on your screen, press the green 'Create Pull Request' button.
7. Fill in all the relevant details such as title and description and after finalize the submission.
You have now successfully edited and submitted changes to our documentation site.
## Creating a New Page
1. From the documentation's GitHub repository, head to the folder called 'pages' and open it.
2. From here you can view all current pages on the documentation site. At the top of your screen press the 'New file' button.
3. You should now be able to view the page you have created. Remember when renaming the document to put .mdx at the end of the file name.
4. From here make the changes you wish to make. Such as creating a title, sub-title and body text.
5. At the bottom of the screen will be a 'Propose Changes' box, fill in all the relevant details such as title and description then press the green 'Propose Changes' button.
6. Your changes have been saved, to submit them for review, located on your screen, press the greem 'Create Pull Request' button.
7. Fill in all the relevant details such as title and description and after finalize the submission.
You have now successfully created and submitted changes to our documentation site.

View File

@ -49,7 +49,7 @@
"storybook-addon-next": "^1.6.9",
"storybook-react-i18next": "^1.1.2",
"tailwindcss": "^3.2.1",
"typescript": "^4.7.4",
"typescript": "^4.9.4",
"vite": "^2.9.15"
}
}

View File

@ -24,6 +24,6 @@
"@types/node": "16.9.1",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -331,7 +331,7 @@ export default function App(props: {
const { t } = useLocale();
return (
<Shell large isPublic heading={t("app_store")} backPath="/apps" withoutSeo>
<Shell smallHeading isPublic heading={t("app_store")} backPath="/apps" withoutSeo>
<HeadSeo
title={props.name}
description={props.description}

View File

@ -38,6 +38,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { HttpError } from "@calcom/lib/http-error";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import slugify from "@calcom/lib/slugify";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { AddressInput, Button, EmailInput, Form, PhoneInput, Tooltip, Group, RadioField } from "@calcom/ui";
import {
@ -57,7 +58,6 @@ import useRouterQuery from "@lib/hooks/useRouterQuery";
import createBooking from "@lib/mutations/bookings/create-booking";
import createRecurringBooking from "@lib/mutations/bookings/create-recurring-booking";
import { parseDate, parseRecurringDates } from "@lib/parseDate";
import slugify from "@lib/slugify";
import Gates, { Gate, GateState } from "@components/Gates";
import BookingDescription from "@components/booking/BookingDescription";

View File

@ -1,6 +1,8 @@
import { ErrorMessage } from "@hookform/error-message";
import { zodResolver } from "@hookform/resolvers/zod";
import { isValidPhoneNumber } from "libphonenumber-js";
import { Trans } from "next-i18next";
import Link from "next/link";
import { useEffect } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { z } from "zod";
@ -216,7 +218,15 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
{t("edit_location")}
</h3>
{!booking && (
<p className="text-sm text-gray-400">{t("this_input_will_shown_booking_this_event")}</p>
<p className="text-sm text-gray-400">
<Trans i18nKey="cant_find_the_right_video_app_visit_our_app_store">
Can&apos;t find the right video app? Visit our
<Link className="cursor-pointer text-blue-500 underline" href="/apps/categories/video">
App Store
</Link>
.
</Trans>
</p>
)}
</div>
<div className="mt-3 text-center sm:mt-0 sm:text-left" />

View File

@ -12,11 +12,10 @@ import { z } from "zod";
import { EventLocationType, getEventLocationType, MeetLocationType } from "@calcom/app-store/locations";
import { CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { slugify } from "@calcom/lib/slugify";
import { Button, Label, Select, SettingsToggle, Skeleton, TextField } from "@calcom/ui";
import { FiEdit2, FiCheck, FiX, FiPlus } from "@calcom/ui/components/icon";
import { slugify } from "@lib/slugify";
import { EditLocationDialog } from "@components/dialog/EditLocationDialog";
import LocationSelect, {
SingleValueLocationOption,
@ -150,6 +149,7 @@ export const EventSetupTab = (
options={locationOptions}
isSearchable={false}
className="block w-full min-w-0 flex-1 rounded-sm text-sm"
menuPlacement="auto"
onChange={(e: SingleValueLocationOption) => {
if (e?.value) {
const newLocationType = e.value;

View File

@ -5,7 +5,7 @@ import { FormEvent, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import turndownService from "@calcom/lib/turndownService";
import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react";
import { Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui";
import { Avatar } from "@calcom/ui";
@ -142,7 +142,7 @@ const UserProfile = (props: IUserProfileProps) => {
<Label className="mb-2 block text-sm font-medium text-gray-700">{t("about")}</Label>
<Editor
getText={() => md.render(getValues("bio") || user?.bio || "")}
setText={(value: string) => setValue("bio", turndownService.turndown(value))}
setText={(value: string) => setValue("bio", turndown(value))}
excludedToolbarItems={["blockType"]}
/>
<p className="mt-2 font-sans text-sm font-normal text-gray-600 dark:text-white">

View File

@ -32,7 +32,7 @@ const Member = ({ member, teamName }: { member: MemberType; teamName: string | n
{!isBioEmpty ? (
<>
<div
className="dark:text-darkgray-600 text-s text-gray-500"
className="dark:text-darkgray-600 text-sm text-gray-500 [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
dangerouslySetInnerHTML={{ __html: md.render(member.bio || "") }}
/>
</>

View File

@ -1,7 +1,7 @@
import classNames from "classnames";
import { APP_NAME, LOGO } from "@calcom/lib/constants";
import { Credits, HeadSeo } from "@calcom/ui";
import { HeadSeo } from "@calcom/ui";
import Loader from "@components/Loader";
@ -35,10 +35,7 @@ export default function AuthContainer(props: React.PropsWithChildren<Props>) {
<div className="mx-2 rounded-md border border-gray-200 bg-white px-4 py-10 sm:px-10">
{props.children}
</div>
<div className="mt-8 text-center text-sm text-gray-600">
{props.footerText}
<Credits />
</div>
<div className="mt-8 text-center text-sm text-gray-600">{props.footerText}</div>
</div>
</div>
);

View File

@ -1 +0,0 @@
export * from "@calcom/lib/availability";

View File

@ -1,2 +0,0 @@
// TODO: Remove this file once everything is imported from `@calcom/lib`
export * from "@calcom/lib/constants";

View File

@ -1 +0,0 @@
export * from "@calcom/lib/weekday";

View File

@ -1,3 +0,0 @@
/* Prefer import from `@calcom/lib/isOutOfBounds` */
export * from "@calcom/lib/isOutOfBounds";
export { default } from "@calcom/lib/isOutOfBounds";

View File

@ -1 +0,0 @@
export * from "@calcom/core/location";

View File

@ -1 +0,0 @@
export { default } from "@calcom/prisma";

View File

@ -1,2 +0,0 @@
// TODO: Remove this file once everything is imported from `@calcom/lib`
export * from "@calcom/lib/random";

View File

@ -1,3 +0,0 @@
/** Prefer import from `@calcom/lib/slots` */
export * from "@calcom/lib/slots";
export { default } from "@calcom/lib/slots";

View File

@ -1,3 +0,0 @@
// TODO: Remove this file once every `classNames` is imported from `@calcom/lib`
export * from "@calcom/lib/slugify";
export { default } from "@calcom/lib/slugify";

View File

@ -164,6 +164,6 @@
"tailwindcss": "^3.2.1",
"ts-jest": "^28.0.8",
"ts-node": "^10.9.1",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -146,7 +146,7 @@ export default function User(props: inferSSRProps<typeof getServerSideProps> & E
{!isBioEmpty && (
<>
<div
className="dark:text-darkgray-600 text-s text-gray-500"
className="dark:text-darkgray-600 text-sm text-gray-500 [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
dangerouslySetInnerHTML={{ __html: md.render(user.bio || "") }}
/>
</>

View File

@ -17,14 +17,14 @@ import { ErrorCode, isPasswordValid, verifyPassword } from "@calcom/lib/auth";
import { APP_NAME, IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
import { symmetricDecrypt } from "@calcom/lib/crypto";
import { defaultCookies } from "@calcom/lib/default-cookies";
import { randomString } from "@calcom/lib/random";
import rateLimit from "@calcom/lib/rateLimit";
import { serverConfig } from "@calcom/lib/serverConfig";
import slugify from "@calcom/lib/slugify";
import prisma from "@calcom/prisma";
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
import CalComAdapter from "@lib/auth/next-auth-custom-adapter";
import { randomString } from "@lib/random";
import slugify from "@lib/slugify";
import { GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, IS_GOOGLE_LOGIN_ENABLED } from "@server/lib/constants";

View File

@ -4,10 +4,9 @@ import { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs";
import { sendPasswordResetEmail } from "@calcom/emails";
import { PASSWORD_RESET_EXPIRY_HOURS } from "@calcom/emails/templates/forgot-password-email";
import { getTranslation } from "@calcom/lib/server/i18n";
import prisma from "@calcom/prisma";
import { getTranslation } from "@server/lib/i18n";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const t = await getTranslation(req.body.language ?? "en", "common");

View File

@ -2,11 +2,10 @@ import { IdentityProvider } from "@prisma/client";
import { NextApiRequest, NextApiResponse } from "next";
import { hashPassword } from "@calcom/lib/auth";
import slugify from "@calcom/lib/slugify";
import { closeComUpsertTeamUser } from "@calcom/lib/sync/SyncServiceManager";
import prisma from "@calcom/prisma";
import slugify from "@lib/slugify";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") {
return;

View File

@ -4,11 +4,10 @@ import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs";
import { sendOrganizerRequestReminderEmail } from "@calcom/emails";
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
import { getTranslation } from "@calcom/lib/server/i18n";
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { getTranslation } from "@server/lib/i18n";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const apiKey = req.headers.authorization || req.query.apiKey;
if (process.env.CRON_API_KEY !== apiKey) {

View File

@ -19,6 +19,7 @@ export default function Apps({ apps }: InferGetStaticPropsType<typeof getStaticP
<Shell
isPublic
backPath="/apps"
smallHeading
heading={
<>
<Link
@ -33,8 +34,7 @@ export default function Apps({ apps }: InferGetStaticPropsType<typeof getStaticP
</span>
)}
</>
}
large>
}>
<div className="mb-16">
<div className="grid-col-1 grid grid-cols-1 gap-3 md:grid-cols-3">
{apps.map((app) => {

View File

@ -9,6 +9,7 @@ import { FaGoogle } from "react-icons/fa";
import { SAMLLogin } from "@calcom/features/auth/SAMLLogin";
import { isSAMLLoginEnabled, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml";
import { WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
@ -17,7 +18,6 @@ import { Alert, Button, EmailField, PasswordField } from "@calcom/ui";
import { FiArrowLeft } from "@calcom/ui/components/icon";
import { ErrorCode, getSession } from "@lib/auth";
import { WEBAPP_URL, WEBSITE_URL } from "@lib/config/constants";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import AddToHomescreen from "@components/AddToHomescreen";
@ -149,7 +149,7 @@ export default function Login({
</div>
<PasswordField
id="password"
autoComplete="current-password"
autoComplete="off"
required
className="mb-0"
{...register("password")}

View File

@ -255,6 +255,7 @@ export default function Success(props: SuccessProps) {
if (!sdkActionManager) return;
// TODO: We should probably make it consistent with Webhook payload. Some data is not available here, as and when requirement comes we can add
sdkActionManager.fire("bookingSuccessful", {
booking: bookingInfo,
eventType,
date: date.toString(),
duration: calculatedDuration,

View File

@ -3,11 +3,11 @@ import { z } from "zod";
import { privacyFilteredLocations, LocationObject } from "@calcom/core/location";
import { parseRecurringEvent } from "@calcom/lib";
import { getWorkingHours } from "@calcom/lib/availability";
import { availiblityPageEventTypeSelect } from "@calcom/prisma";
import prisma from "@calcom/prisma";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { getWorkingHours } from "@lib/availability";
import { GetBookingType } from "@lib/getBooking";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import { EmbedProps } from "@lib/withEmbedSsr";

View File

@ -97,7 +97,10 @@ const Item = ({ type, group, readOnly }: { type: EventType; group: EventTypeGrou
</span>
)}
</div>
<EventTypeDescription eventType={type} />
<EventTypeDescription
// @ts-expect-error FIXME We have a type mismtach here @hariombalhara @sean-brydon
eventType={type}
/>
</Link>
);
};

View File

@ -7,10 +7,9 @@ import { z } from "zod";
import { getSession } from "@calcom/lib/auth";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { User } from "@calcom/prisma/client";
import prisma from "@calcom/prisma";
import { Button, StepCard, Steps } from "@calcom/ui";
import prisma from "@lib/prisma";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import { ConnectedCalendars } from "@components/getting-started/steps-views/ConnectCalendars";

View File

@ -5,6 +5,7 @@ import { Controller, useForm } from "react-hook-form";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { nameOfDay } from "@calcom/lib/weekday";
import { RouterOutputs, trpc } from "@calcom/trpc/react";
import {
Button,
@ -20,7 +21,6 @@ import {
} from "@calcom/ui";
import { withQuery } from "@lib/QueryCell";
import { nameOfDay } from "@lib/core/i18n/weekday";
import { ssrInit } from "@server/lib/ssr";

View File

@ -10,7 +10,7 @@ import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { ErrorCode } from "@calcom/lib/auth";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import turndownService from "@calcom/lib/turndownService";
import turndown from "@calcom/lib/turndownService";
import { TRPCClientErrorLike } from "@calcom/trpc/client";
import { trpc } from "@calcom/trpc/react";
import { AppRouter } from "@calcom/trpc/server/routers/_app";
@ -370,7 +370,7 @@ const ProfileForm = ({
<Editor
getText={() => md.render(formMethods.getValues("bio") || "")}
setText={(value: string) => {
formMethods.setValue("bio", turndownService.turndown(value), { shouldDirty: true });
formMethods.setValue("bio", turndown(value), { shouldDirty: true });
}}
excludedToolbarItems={["blockType"]}
/>

View File

@ -5,15 +5,16 @@ import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import LicenseRequired from "@calcom/features/ee/common/components/v2/LicenseRequired";
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import prisma from "@calcom/prisma";
import { inferSSRProps } from "@calcom/types/inferSSRProps";
import { Alert, Button, EmailField, PasswordField, TextField, HeadSeo } from "@calcom/ui";
import { asStringOrNull } from "@calcom/web/lib/asStringOrNull";
import { WEBAPP_URL } from "@calcom/web/lib/config/constants";
import prisma from "@calcom/web/lib/prisma";
import { IS_GOOGLE_LOGIN_ENABLED } from "@calcom/web/server/lib/constants";
import { ssrInit } from "@calcom/web/server/lib/ssr";
import { Alert, Button, EmailField, HeadSeo, PasswordField, TextField } from "@calcom/ui";
import { asStringOrNull } from "../lib/asStringOrNull";
import { IS_GOOGLE_LOGIN_ENABLED } from "../server/lib/constants";
import { ssrInit } from "../server/lib/ssr";
type FormValues = {
username: string;

View File

@ -99,7 +99,7 @@ function TeamPage({ team }: TeamPageProps) {
{!isBioEmpty && (
<>
<div
className="dark:text-darkgray-600 text-s text-gray-500"
className="dark:text-darkgray-600 text-sm text-gray-500 [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
dangerouslySetInnerHTML={{ __html: md.render(team.bio || "") }}
/>
</>

View File

@ -2,11 +2,11 @@ import { GetServerSidePropsContext } from "next";
import { privacyFilteredLocations, LocationObject } from "@calcom/core/location";
import { parseRecurringEvent } from "@calcom/lib";
import { getWorkingHours } from "@calcom/lib/availability";
import prisma from "@calcom/prisma";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { asStringOrNull } from "@lib/asStringOrNull";
import { getWorkingHours } from "@lib/availability";
import getBooking, { GetBookingType } from "@lib/getBooking";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import { EmbedProps } from "@lib/withEmbedSsr";

View File

@ -1,8 +1,8 @@
import { expect } from "@playwright/test";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { randomString } from "@calcom/lib/random";
import { randomString } from "../lib/random";
import { test } from "./lib/fixtures";
test.describe.configure({ mode: "parallel" });

View File

@ -1 +0,0 @@
export * from "@calcom/lib/server/i18n";

View File

@ -3,8 +3,7 @@ import { Availability } from "@prisma/client";
import MockDate from "mockdate";
import dayjs from "@calcom/dayjs";
import { getAvailabilityFromSchedule } from "@lib/availability";
import { getAvailabilityFromSchedule } from "@calcom/lib/availability";
MockDate.set("2021-06-20T11:59:59Z");

View File

@ -2,10 +2,9 @@ import { expect, it } from "@jest/globals";
import MockDate from "mockdate";
import dayjs from "@calcom/dayjs";
import { MINUTES_DAY_END, MINUTES_DAY_START } from "@calcom/lib/availability";
import getSlots from "@calcom/lib/slots";
import { MINUTES_DAY_END, MINUTES_DAY_START } from "@lib/availability";
MockDate.set("2021-06-20T11:59:59Z");
describe("Tests the slot logic", () => {

View File

@ -25,11 +25,11 @@
"react": "^18.2.0"
},
"devDependencies": {
"chokidar": "^3.5.3",
"@types/react": "^18.0.17",
"chokidar": "^3.5.3",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"ts-node": "^10.9.1",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -1,9 +0,0 @@
## How to build an App using the CLI
Refer to https://developer.cal.com/guides/how-to-build-an-app
## TODO
- Merge app-store:watch and app-store commands; introduce app-store --watch
- An app created through CLI should be able to completely skip API validation for testing purposes. Credentials should be created with no API specified specific to the app. It would allow us to test any app end to end not worrying about the corresponding API endpoint.
- Someone can add wrong directory name(which doesn't satisfy slug requirements) manually. How to handle it.
- Allow editing and updating app from the cal app itself - including assets uploading when developing locally.
- Use AppDeclarativeHandler across all apps. Whatever isn't supported in it, support that.

View File

@ -12,5 +12,14 @@
"publisher": "Cal.com",
"email": "help@cal.com",
"description": "Discover radically unique video calls designed to help hybrid-remote teams create, collaborate and celebrate together.",
"__createdUsingCli": true
"__createdUsingCli": true,
"appData": {
"location": {
"linkType": "static",
"type": "integrations:around_video",
"label": "Around Video",
"urlRegExp": "^http(s)?:\\/\\/(www\\.)?around.co\\/[a-zA-Z0-9]*",
"organizerInputPlaceholder": "https://www.around.co/rick"
}
}
}

View File

@ -20,6 +20,7 @@ export default function FormInputFields(props: Props) {
<>
{form.fields?.map((field) => {
if (isRouterLinkedField(field)) {
// @ts-expect-error FIXME @hariombalhara
field = field.routerField;
}
const widget = queryBuilderConfig.widgets[field.type];

View File

@ -12,5 +12,14 @@
"publisher": "Ping.gg",
"email": "support@ping.gg",
"description": "Ping.gg makes high quality video collaborations easier than ever. Think 'Zoom for streamers and creators'. Join a call in 3 clicks, manage audio and video like a pro, and copy-paste your guests straight into OBS",
"__createdUsingCli": true
"__createdUsingCli": true,
"appData": {
"location": {
"linkType": "static",
"type": "integrations:ping_video",
"label": "Ping.gg",
"organizerInputPlaceholder": "https://www.ping.gg/call/theo",
"urlRegExp": "^http(s)?:\\/\\/(www\\.)?ping.gg\\/call\\/[a-zA-Z0-9]*"
}
}
}

View File

@ -11,5 +11,13 @@
"publisher": "Cal.com",
"email": "help@cal.com",
"description": "Your online recording studio. The easiest way to record podcasts and videos in studio quality from anywhere. All from the browser.",
"__createdUsingCli": true
"__createdUsingCli": true,
"appData": {
"location": {
"label": "Riverside Video",
"urlRegExp": "^http(s)?:\\/\\/(www\\.)?riverside.fm\\/studio\\/[a-zA-Z0-9]*",
"type": "integrations:riverside_video",
"linkType": "static"
}
}
}

View File

@ -12,5 +12,14 @@
"publisher": "Cal.com",
"email": "help@cal.com",
"description": "Whereby makes it super simple for collaborating teams to jump on a video call.",
"__createdUsingCli": true
"__createdUsingCli": true,
"appData": {
"location": {
"linkType": "static",
"type": "integrations:whereby_video",
"label": "Whereby Video",
"organizerInputPlaceholder": "https://www.whereby.com/cal",
"urlRegExp": "^http(s)?:\\/\\/(www\\.)?(team.)?whereby.com\\/[a-zA-Z0-9]*"
}
}
}

View File

@ -28,6 +28,7 @@ const config = {
"sv",
"vi",
"no",
"ua",
],
},
reloadOnPrerender: process.env.NODE_ENV !== "production",

View File

@ -28,6 +28,6 @@
"prettier-plugin-tailwindcss": "^0.1.13",
"tailwind-scrollbar": "^2.0.1",
"tailwindcss": "^3.2.1",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -22,14 +22,6 @@ export default class AttendeeScheduledEmail extends BaseEmail {
this.attendee = attendee;
this.showAttendees = showAttendees;
this.t = attendee.language.translate;
if (!this.showAttendees) {
this.calEvent.attendees = [
{
...this.attendee,
},
];
}
}
protected getiCalEventAsString(): string | undefined {

View File

@ -46,8 +46,8 @@
"eslint": "^8.22.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.18",
"typescript": "^4.7.4",
"vite": "^2.9.15",
"tailwindcss": "^3.2.1"
"tailwindcss": "^3.2.1",
"typescript": "^4.9.4",
"vite": "^2.9.15"
}
}

View File

@ -46,7 +46,7 @@
"@vitejs/plugin-react": "^1.3.2",
"eslint": "^8.22.0",
"npm-run-all": "^4.1.5",
"typescript": "^4.7.4",
"typescript": "^4.9.4",
"vite": "^2.9.15"
},
"dependencies": {

View File

@ -25,7 +25,7 @@
"types": "./dist/index.d.ts",
"devDependencies": {
"eslint": "^8.22.0",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
},
"dependencies": {
"@calcom/embed-core": "*"

View File

@ -8,7 +8,7 @@
"@typescript-eslint/utils": "^5.33.1",
"eslint": "^8.22.0",
"ts-node": "^10.9.1",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
},
"devDependencies": {
"@types/eslint": "^8.4.5"

View File

@ -620,6 +620,11 @@ async function handler(req: NextApiRequest & { userId?: number | undefined }) {
});
const newSeat = booking.attendees.length !== 0;
if (!evt.seatsShowAttendees) {
evt.attendees = invitee;
}
/**
* Remember objects are passed into functions as references
* so if you modify it in a inner function it will be modified in the outer function

View File

@ -61,7 +61,7 @@ const LicenseRequired = ({ children, as = "", ...rest }: LicenseRequiredProps) =
};
export const withLicenseRequired =
<T,>(Component: ComponentType<T>) =>
<T extends JSX.IntrinsicAttributes>(Component: ComponentType<T>) =>
// eslint-disable-next-line react/display-name
(hocProps: T) =>
(

View File

@ -51,7 +51,7 @@ const LicenseRequired = ({ children, as = "", ...rest }: LicenseRequiredProps) =
};
export const withLicenseRequired =
<T,>(Component: ComponentType<T>) =>
<T extends JSX.IntrinsicAttributes>(Component: ComponentType<T>) =>
// eslint-disable-next-line react/display-name
(hocProps: T) =>
(

View File

@ -12,7 +12,7 @@ import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
import { getPlaceholderAvatar } from "@calcom/lib/getPlaceholderAvatar";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import objectKeys from "@calcom/lib/objectKeys";
import turndownService from "@calcom/lib/turndownService";
import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react";
import {
Avatar,
@ -223,7 +223,7 @@ const ProfileView = () => {
<Label>{t("about")}</Label>
<Editor
getText={() => md.render(form.getValues("bio") || "")}
setText={(value: string) => form.setValue("bio", turndownService.turndown(value))}
setText={(value: string) => form.setValue("bio", turndown(value))}
excludedToolbarItems={["blockType"]}
/>
</div>
@ -256,7 +256,7 @@ const ProfileView = () => {
<>
<Label className="mt-5 text-black">{t("about")}</Label>
<div
className="dark:text-darkgray-600 text-s text-gray-500"
className="dark:text-darkgray-600 text-sm text-gray-500 [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
dangerouslySetInnerHTML={{ __html: md.render(team.bio || "") }}
/>
</>

View File

@ -202,7 +202,7 @@ const CreateEventTypeDialog = () => {
min="10"
placeholder="15"
label={t("length")}
className="pr-20"
className="pr-4"
{...register("length", { valueAsNumber: true })}
addOnSuffix={t("minutes")}
/>

View File

@ -117,7 +117,6 @@ const DuplicateDialog = () => {
min="10"
placeholder="15"
label={t("length")}
className="pr-20"
{...register("length", { valueAsNumber: true })}
addOnSuffix={t("minutes")}
/>

View File

@ -188,6 +188,7 @@ type LayoutProps = {
withoutSeo?: boolean;
// Gives the ability to include actions to the right of the heading
actions?: JSX.Element;
smallHeading?: boolean;
};
const CustomBrandingContainer = () => {
@ -785,7 +786,8 @@ export function ShellMain(props: LayoutProps) {
const { isLocaleReady } = useLocale();
return (
<>
<div className="mb-6 flex sm:mt-0 lg:mb-10">
<div
className={classNames("mb-6 flex items-center sm:mt-0", props.smallHeading ? "lg:mb-7" : "lg:mb-10")}>
{!!props.backPath && (
<Button
variant="icon"
@ -795,7 +797,7 @@ export function ShellMain(props: LayoutProps) {
}
StartIcon={FiArrowLeft}
aria-label="Go Back"
className="ltr:mr-2 rtl:ml-2"
className="mt-1 ltr:mr-2 rtl:ml-2"
/>
)}
{props.heading && (
@ -803,7 +805,11 @@ export function ShellMain(props: LayoutProps) {
{props.HeadingLeftIcon && <div className="ltr:mr-4">{props.HeadingLeftIcon}</div>}
<div className={classNames("w-full ltr:mr-4 rtl:ml-4 sm:block", props.headerClassName)}>
{props.heading && (
<h1 className="font-cal max-w-28 sm:max-w-72 md:max-w-80 mt-1 hidden truncate text-2xl font-semibold tracking-wide text-black sm:block xl:max-w-full">
<h1
className={classNames(
"font-cal max-w-28 sm:max-w-72 md:max-w-80 mt-1 hidden truncate font-semibold tracking-wide text-black sm:block xl:max-w-full",
props.smallHeading ? "text-base" : "text-2xl"
)}>
{!isLocaleReady ? <SkeletonText invisible /> : props.heading}
</h1>
)}

View File

@ -3,7 +3,8 @@ export function getErrorFromUnknown(cause: unknown): Error & { statusCode?: numb
return cause;
}
if (typeof cause === "string") {
// @ts-expect-error https://github.com/tc39/proposal-error-cause
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore https://github.com/tc39/proposal-error-cause
return new Error(cause, { cause });
}

View File

@ -31,6 +31,6 @@
"@calcom/tsconfig": "*",
"@calcom/types": "*",
"@faker-js/faker": "^7.3.0",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -2,11 +2,48 @@ import TurndownService from "turndown";
const turndownService = new TurndownService();
turndownService.addRule("newLine", {
filter: ["br"],
replacement: () => {
function turndown(html: string | TurndownService.Node): string {
let result = turndownService.turndown(html);
result = result.replaceAll("[<p><br></p>]", "");
if (result === "<p><br></p>") {
result = "";
}
return result;
}
turndownService.addRule("shiftEnter", {
filter: function (node) {
return node.nodeName === "BR" && !!isShiftEnter(node);
},
replacement: function () {
return "<br>";
},
});
turndownService.addRule("enter", {
filter: function (node) {
return node.nodeName === "BR" && !isShiftEnter(node);
},
replacement: function () {
return "<p><br></p>";
},
});
export default turndownService;
function isShiftEnter(node: HTMLElement) {
let currentNode: HTMLElement | null | ParentNode = node;
while (currentNode != null && currentNode.nodeType !== 1) {
currentNode = currentNode.parentElement || currentNode.parentNode;
}
return (
currentNode &&
currentNode.nodeType === 1 &&
currentNode.parentElement &&
currentNode.parentElement.childNodes.length !== 1 // normal enter is <p><br><p> (p has exactly one childNode)
);
}
export default turndown;

View File

@ -0,0 +1,10 @@
-- CreateTable
CREATE TABLE "Deployment" (
"id" INTEGER NOT NULL DEFAULT 1,
"logo" TEXT,
"theme" JSONB,
"licenseKey" TEXT,
"agreedLicenseAt" TIMESTAMP(3),
CONSTRAINT "Deployment_pkey" PRIMARY KEY ("id")
);

View File

@ -8,7 +8,7 @@ datasource db {
generator client {
provider = "prisma-client-js"
previewFeatures = ["interactiveTransactions"]
previewFeatures = []
}
generator zod {
@ -615,6 +615,16 @@ model WorkflowsOnEventTypes {
eventTypeId Int
}
model Deployment {
/// This is a single row table, so we use a fixed id
id Int @id @default(1)
logo String?
/// @zod.custom(imports.DeploymentTheme)
theme Json?
licenseKey String?
agreedLicenseAt DateTime?
}
enum TimeUnit {
DAY @map("day")
HOUR @map("hour")

View File

@ -293,6 +293,24 @@ export const RoutingFormSettings = z
})
.nullable();
export const DeploymentTheme = z
.object({
brand: z.string().default("#292929"),
textBrand: z.string().default("#ffffff"),
darkBrand: z.string().default("#fafafa"),
textDarkBrand: z.string().default("#292929"),
bookingHighlight: z.string().default("#10B981"),
bookingLightest: z.string().default("#E1E1E1"),
bookingLighter: z.string().default("#ACACAC"),
bookingLight: z.string().default("#888888"),
bookingMedian: z.string().default("#494949"),
bookingDark: z.string().default("#313131"),
bookingDarker: z.string().default("#292929"),
fontName: z.string().default("Cal Sans"),
fontSrc: z.string().default("https://cal.com/cal.ttf"),
})
.optional();
export type ZodDenullish<T extends ZodTypeAny> = T extends ZodNullable<infer U> | ZodOptional<infer U>
? ZodDenullish<U>
: T;
@ -335,7 +353,7 @@ export function denullishShape<
* @returns The constructed tuple array from the given object
* @see https://github.com/3x071c/lsg-remix/blob/e2a9592ba3ec5103556f2cf307c32f08aeaee32d/app/lib/util/entries.ts
*/
export const entries = <O>(
export const entries = <O extends Record<string, unknown>>(
obj: O
): {
readonly [K in keyof O]: [K, O[K]];

View File

@ -676,7 +676,13 @@ export const eventTypesRouter = router({
}),
duplicate: eventOwnerProcedure.input(EventTypeDuplicateInput.strict()).mutation(async ({ ctx, input }) => {
try {
const { id: originalEventTypeId, title: newEventTitle, slug: newSlug } = input;
const {
id: originalEventTypeId,
title: newEventTitle,
slug: newSlug,
description: newDescription,
length: newLength,
} = input;
const eventType = await ctx.prisma.eventType.findUnique({
where: {
id: originalEventTypeId,
@ -735,6 +741,8 @@ export const eventTypesRouter = router({
...rest,
title: newEventTitle,
slug: newSlug,
description: newDescription,
length: newLength,
locations: locations ?? undefined,
teamId: team ? team.id : undefined,
users: users ? { connect: users.map((user) => ({ id: user.id })) } : undefined,

View File

@ -1,7 +1,6 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import {Alert} from './Alert';
import { Examples, Example, Note, Title, CustomArgsTable, VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Alert } from './Alert';
<Meta title="UI/Alert" component={Alert} />

View File

@ -6,9 +6,9 @@ import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { AppFrontendPayload as App } from "@calcom/types/App";
import type { CredentialFrontendPayload as Credential } from "@calcom/types/Credential";
import { FiChevronLeft, FiChevronRight, FiSearch } from "@calcom/ui/components/icon";
import { EmptyScreen } from "../empty-screen";
import { FiChevronLeft, FiChevronRight, FiSearch } from "../icon";
import { AppCard } from "./AppCard";
export function useShouldShowArrows() {

View File

@ -1,18 +1,7 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Icon } from "@calcom/ui";
import { AppStoreCategories as Categories } from "./Categories";
import { _SBAppCategoryList } from "./_storybookData";
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title, CustomArgsTable, VariantsTable, VariantRow } from '@calcom/storybook/components';
import { AppStoreCategories as Categories } from './Categories';
import { _SBAppCategoryList } from './_storybookData';
<Meta title="UI/apps/Categories" component={Categories} />
@ -24,8 +13,8 @@ Categories that is used in our appstore.
<CustomArgsTable of={Categories} />
## Examples
We don't currently mock translations in storybook so the stories will display placeholder text.
<Categories categories={_SBAppCategoryList} />

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import {Avatar} from './Avatar';
import {AvatarGroup} from './AvatarGroup';

View File

@ -1,7 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import { Breadcrumb } from './Breadcrumb';
<Meta title="UI/Breadcrumbs" component={Breadcrumb} />

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import Credits from './Credits';
<Meta title="UI/Credits" component={Credits} />

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import {Divider, VerticalDivider} from './Divider';
<Meta title="UI/Divider" component={Divider} />

View File

@ -1,30 +1,30 @@
import { $generateHtmlFromNodes, $generateNodesFromDOM } from "@lexical/html";
import { $isLinkNode, TOGGLE_LINK_COMMAND } from "@lexical/link";
import {
$isListNode,
INSERT_ORDERED_LIST_COMMAND,
INSERT_UNORDERED_LIST_COMMAND,
REMOVE_LIST_COMMAND,
$isListNode,
ListNode,
REMOVE_LIST_COMMAND,
} from "@lexical/list";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { $createHeadingNode, $isHeadingNode } from "@lexical/rich-text";
import { $wrapNodes, $isAtNodeEnd } from "@lexical/selection";
import { $isAtNodeEnd, $wrapNodes } from "@lexical/selection";
import { $getNearestNodeOfType, mergeRegister } from "@lexical/utils";
import classNames from "classnames";
import {
SELECTION_CHANGE_COMMAND,
FORMAT_TEXT_COMMAND,
$getSelection,
$isRangeSelection,
$createParagraphNode,
RangeSelection,
NodeSelection,
GridSelection,
$getRoot,
$getSelection,
$insertNodes,
LexicalEditor,
$isRangeSelection,
EditorState,
FORMAT_TEXT_COMMAND,
GridSelection,
LexicalEditor,
NodeSelection,
RangeSelection,
SELECTION_CHANGE_COMMAND,
} from "lexical";
import { useCallback, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
@ -387,7 +387,6 @@ export default function ToolbarPlugin(props: TextEditorProps) {
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
}
}, [editor, isLink]);
console.log("TEST", blockTypeToBlockName[blockType]);
return (
<div className="toolbar flex" ref={toolbarRef}>
<>

View File

@ -68,7 +68,6 @@
.editor-paragraph {
margin: 0;
margin-bottom: 8px;
position: relative;
}

View File

@ -1,7 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import Checkbox from './Checkbox';

View File

@ -1,6 +1,7 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable, VariantRow,VariantsTable} from '@calcom/storybook/components'
import { Icon,Select,UnstyledSelect,InputFieldWithSelect } from "@calcom/ui";
import { Select, UnstyledSelect } from "../select";
import { InputFieldWithSelect } from './Input';
import {InputField} from "./Input"

View File

@ -1,5 +1,6 @@
import merge from "lodash/merge";
import { NextSeo, NextSeoProps } from "next-seo";
import { useRouter } from "next/router";
import {
AppImageProps,
@ -10,6 +11,7 @@ import {
} from "@calcom/lib/OgImages";
import { getBrowserInfo } from "@calcom/lib/browser/browser.utils";
import { APP_NAME } from "@calcom/lib/constants";
import isCalcom from "@calcom/lib/isCalcom";
import { seoConfig, getSeoImage } from "@calcom/lib/next-seo.config";
import { truncateOnWord } from "@calcom/lib/text";
@ -72,13 +74,15 @@ const buildSeoMeta = (pageProps: {
};
export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
const defaultUrl = getBrowserInfo()?.url;
// build the canonical url to ensure it's always cal.com (not app.cal.com)
const router = useRouter();
const calcomUrl = (`https://cal.com` + (router.asPath === "/" ? "" : router.asPath)).split("?")[0]; // cut off search params
const defaultUrl = isCalcom ? calcomUrl : getBrowserInfo()?.url;
const { title, description, siteName, canonical = defaultUrl, nextSeoProps = {}, app, meeting } = props;
const image = getSeoImage("ogImage") + constructGenericImage({ title, description });
const truncatedDescription = truncateOnWord(description, 158);
const pageTitle = title + " | " + APP_NAME;
let seoObject = buildSeoMeta({
title: pageTitle,

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable,VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import { List, ListItem } from './List';
<Meta title="UI/List" component={List} />

View File

@ -8,7 +8,14 @@ import {
} from "@calcom/lib/date-fns";
import { FiGlobe } from "@calcom/ui/components/icon";
import { Attendee } from ".prisma/client";
type Attendee = {
id: number;
email: string;
name: string;
timeZone: string;
locale: string | null;
bookingId: number | null;
};
interface MeetingTimeInTimezonesProps {
attendees: Attendee[];

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title, VariantsTable, VariantColumn, RowTitles, CustomArgsTable} from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import { Skeleton, SkeletonAvatar, SkeletonText, SkeletonButton, SkeletonContainer } from './';

View File

@ -2,13 +2,13 @@ import React, { FC } from "react";
import { IconType } from "react-icons/lib";
import {
Button,
Dropdown,
DropdownMenuContent,
DropdownMenuItem,
DropdownItem,
DropdownMenuPortal,
DropdownMenuTrigger,
Button,
ButtonBaseProps,
} from "@calcom/ui";
import { FiChevronDown, FiMoreHorizontal } from "@calcom/ui/components/icon";

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title, VariantsTable, VariantColumn, RowTitles, CustomArgsTable} from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import { SuccessToast,ErrorToast,WarningToast,DefaultToast } from './';

View File

@ -1,6 +1,5 @@
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import { Examples, Example, Note, Title,CustomArgsTable,VariantsTable, VariantRow } from '@calcom/storybook/components'
import { Icon } from "@calcom/ui";
import { TopBanner } from './TopBanner'
<Meta title="UI/TopBanner" component={TopBanner} />

View File

@ -21,9 +21,13 @@ const RadioArea = React.forwardRef<HTMLInputElement, RadioAreaProps>(
);
}
);
interface RadioAreaGroupProps extends Omit<React.ComponentPropsWithoutRef<"div">, "onChange"> {
type MaybeArray<T> = T[] | T;
type ChildrenOfType<T extends React.ElementType> = MaybeArray<
React.ReactElement<React.ComponentPropsWithoutRef<T>>
>;
interface RadioAreaGroupProps extends Omit<React.ComponentPropsWithoutRef<"div">, "onChange" | "children"> {
onChange?: (value: string) => void;
children: ChildrenOfType<typeof RadioArea>;
}
const RadioAreaGroup = ({ children, className, onChange, ...passThroughProps }: RadioAreaGroupProps) => {

View File

@ -40,6 +40,6 @@
"@calcom/tsconfig": "*",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
"typescript": "^4.9.4"
}
}

View File

@ -5253,9 +5253,9 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-accordion@^1.0.0":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.0.1.tgz"
integrity sha512-Ka7BQoyRRPwsOb0YEv0fQU8V8aCXCxAzNVI5BRN7WmPG2E1zQKKxmb86NVDqIj6uSnaahJ1E5S6bX5Lk9hTK+g==
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-accordion/-/react-accordion-1.1.0.tgz#8db063b9eaeb32ca90ffec74e190dab104b56522"
integrity sha512-CNN9ZBgCK4i4SX7gFk5s8095j55DUWi85vwRNfkfBLs0QdAG5Tb4ku6sBeugCAiLvsmxw481GyNl+C3stoJVBQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.0"
@ -5263,6 +5263,7 @@
"@radix-ui/react-collection" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.0"
"@radix-ui/react-context" "1.0.0"
"@radix-ui/react-direction" "1.0.0"
"@radix-ui/react-id" "1.0.0"
"@radix-ui/react-primitive" "1.0.1"
"@radix-ui/react-use-controllable-state" "1.0.0"
@ -5753,10 +5754,10 @@
"@radix-ui/react-use-callback-ref" "1.0.0"
"@radix-ui/react-use-controllable-state" "1.0.0"
"@radix-ui/react-roving-focus@1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.1.tgz"
integrity sha512-TB76u5TIxKpqMpUAuYH2VqMhHYKa+4Vs1NHygo/llLvlffN6mLVsFhz0AnSFlSBAvTBYVHYAkHAyEt7x1gPJOA==
"@radix-ui/react-roving-focus@1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.2.tgz#d8ac2e3b8006697bdfc2b0eb06bef7e15b6245de"
integrity sha512-HLK+CqD/8pN6GfJm3U+cqpqhSKYAWiOJDe+A+8MfxBnOue39QEeMa43csUn2CXCHQT0/mewh1LrrG4tfkM9DMA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.0"
@ -5852,9 +5853,9 @@
"@radix-ui/react-use-size" "1.0.0"
"@radix-ui/react-tabs@^1.0.0":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.1.tgz"
integrity sha512-mVNEwHwgjy2G9F7b39f9VY+jF0QUZykTm0Sdv+Uz6KC4KOEIa4HLDiHU8MeEZluRtZE3aqGYDhl93O7QbJDwhg==
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.2.tgz#8f5ec73ca41b151a413bdd6e00553408ff34ce07"
integrity sha512-gOUwh+HbjCuL0UCo8kZ+kdUEG8QtpdO4sMQduJ34ZEz0r4922g9REOBM+vIsfwtGxSug4Yb1msJMJYN2Bk8TpQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.0"
@ -5863,7 +5864,7 @@
"@radix-ui/react-id" "1.0.0"
"@radix-ui/react-presence" "1.0.0"
"@radix-ui/react-primitive" "1.0.1"
"@radix-ui/react-roving-focus" "1.0.1"
"@radix-ui/react-roving-focus" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.0"
"@radix-ui/react-toggle-group@^1.0.0":
@ -9427,12 +9428,12 @@
"@xmldom/xmldom@^0.7.5":
version "0.7.5"
resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d"
integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==
"@xmldom/xmldom@^0.8.1":
version "0.8.2"
resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.2.tgz"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.2.tgz#b695ff674e8216efa632a3d36ad51ae9843380c0"
integrity sha512-+R0juSseERyoPvnBQ/cZih6bpF7IpCXlWbHRoCRzYzqpz6gWHOgf8o4MOEf6KBVuOyqU+gCNLkCWVIJAro8XyQ==
"@xtuc/ieee754@^1.2.0":
@ -18203,7 +18204,7 @@ jose@^4.10.0:
jose@^4.9.3:
version "4.11.1"
resolved "https://registry.npmjs.org/jose/-/jose-4.11.1.tgz"
resolved "https://registry.yarnpkg.com/jose/-/jose-4.11.1.tgz#8f7443549befe5bddcf4bae664a9cbc1a62da4fa"
integrity sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==
jpeg-js@0.4.2:
@ -22125,17 +22126,17 @@ playwright-core@1.25.0:
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.0.tgz"
integrity sha512-kZ3Jwaf3wlu0GgU0nB8UMQ+mXFTqBIFz9h1svTlNduNKjnbPXFxw7mJanLVjqxHJRn62uBfmgBj93YHidk2N5Q==
playwright-core@1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.2.tgz#2e8347e7e8522409f22b244e600e703b64022406"
integrity sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==
playwright-core@1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.30.0.tgz#de987cea2e86669e3b85732d230c277771873285"
integrity sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==
playwright@^1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.29.2.tgz#d6a0a3e8e44f023f7956ed19ffa8af915a042769"
integrity sha512-hKBYJUtdmYzcjdhYDkP9WGtORwwZBBKAW8+Lz7sr0ZMxtJr04ASXVzH5eBWtDkdb0c3LLFsehfPBTRfvlfKJOA==
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.30.0.tgz#b1d7be2d45d97fbb59f829f36f521f12010fe072"
integrity sha512-ENbW5o75HYB3YhnMTKJLTErIBExrSlX2ZZ1C/FzmHjUYIfxj/UnI+DWpQr992m+OQVSg0rCExAOlRwB+x+yyIg==
dependencies:
playwright-core "1.29.2"
playwright-core "1.30.0"
pngjs@^3.0.0, pngjs@^3.3.0, pngjs@^3.3.3:
version "3.4.0"
@ -22375,7 +22376,7 @@ preact@^10.5.9:
preact@^10.6.3:
version "10.11.3"
resolved "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.11.3.tgz#8a7e4ba19d3992c488b0785afcc0f8aa13c78d19"
integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==
prelude-ls@^1.2.1:
@ -26750,15 +26751,20 @@ typescript@^4.9.3:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz"
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
typescript@^4.9.4:
version "4.9.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
tzdata@^1.0.30:
version "1.0.36"
resolved "https://registry.yarnpkg.com/tzdata/-/tzdata-1.0.36.tgz#e5f3998d5e95e0e65dee417ae917a16314df69e9"
integrity sha512-QxRODDsXS8UVxlPazCZXplqVuD6mCe7tSyDE5SCSHXv1nmrfflXxNH4pD+fjU8KJwePhWqhp6n+FpygQeGLv7w==
ua-parser-js@^1.0.2:
version "1.0.32"
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.32.tgz"
integrity sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==
version "1.0.33"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.33.tgz#f21f01233e90e7ed0f059ceab46eb190ff17f8f4"
integrity sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"