Merge branch 'main' into chore-team-metadata-table
This commit is contained in:
commit
1f685822c1
|
@ -19,12 +19,12 @@ Fixes # (issue)
|
||||||
|
|
||||||
<!-- Please delete bullets that are not relevant. -->
|
<!-- Please delete bullets that are not relevant. -->
|
||||||
|
|
||||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
- Bug fix (non-breaking change which fixes an issue)
|
||||||
- [ ] Chore (refactoring code, technical debt, workflow improvements)
|
- Chore (refactoring code, technical debt, workflow improvements)
|
||||||
- [ ] New feature (non-breaking change which adds functionality)
|
- New feature (non-breaking change which adds functionality)
|
||||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
- [ ] Tests (Unit/Integration/E2E or any other test)
|
- Tests (Unit/Integration/E2E or any other test)
|
||||||
- [ ] This change requires a documentation update
|
- This change requires a documentation update
|
||||||
|
|
||||||
## How should this be tested?
|
## How should this be tested?
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v7
|
- uses: actions/stale@v7
|
||||||
with:
|
with:
|
||||||
|
days-before-close: -1
|
||||||
days-before-issue-stale: 60
|
days-before-issue-stale: 60
|
||||||
days-before-issue-close: -1
|
days-before-issue-close: -1
|
||||||
days-before-pr-stale: 14
|
days-before-pr-stale: 14
|
||||||
days-before-pr-close: 7
|
days-before-pr-close: -1
|
||||||
stale-pr-message: "This PR is being marked as stale due to inactivity."
|
stale-pr-message: "This PR is being marked as stale due to inactivity."
|
||||||
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued."
|
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued."
|
||||||
operations-per-run: 100
|
operations-per-run: 100
|
||||||
|
|
|
@ -56,6 +56,41 @@ jobs:
|
||||||
uses: ./.github/workflows/production-build.yml
|
uses: ./.github/workflows/production-build.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
build-without-database:
|
||||||
|
name: Production build (without database)
|
||||||
|
needs: [changes]
|
||||||
|
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||||
|
uses: ./.github/workflows/production-build-without-database.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
e2e:
|
||||||
|
name: E2E tests
|
||||||
|
needs: [changes, lint, build]
|
||||||
|
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||||
|
uses: ./.github/workflows/e2e.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
e2e-app-store:
|
||||||
|
name: E2E App Store tests
|
||||||
|
needs: [changes, lint, build]
|
||||||
|
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||||
|
uses: ./.github/workflows/e2e-app-store.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
e2e-embed:
|
||||||
|
name: E2E embeds tests
|
||||||
|
needs: [changes, lint, build]
|
||||||
|
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||||
|
uses: ./.github/workflows/e2e-embed.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
e2e-embed-react:
|
||||||
|
name: E2E React embeds tests
|
||||||
|
needs: [changes, lint, build]
|
||||||
|
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||||
|
uses: ./.github/workflows/e2e-embed-react.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
analyze:
|
analyze:
|
||||||
name: Analyze Build
|
name: Analyze Build
|
||||||
needs: [changes, build]
|
needs: [changes, build]
|
||||||
|
@ -64,7 +99,7 @@ jobs:
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
required:
|
required:
|
||||||
needs: [changes, lint, type-check, test, build]
|
needs: [changes, lint, type-check, test, build, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
|
||||||
if: always()
|
if: always()
|
||||||
runs-on: buildjet-4vcpu-ubuntu-2204
|
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -2,9 +2,6 @@ name: Pre-release checks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
changes:
|
changes:
|
||||||
|
|
|
@ -67,5 +67,5 @@ const getPageProps = async ({ params }: { params: Record<string, string | string
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-expect-error getData arg
|
// @ts-expect-error getData arg
|
||||||
export default WithLayout({ getData: getPageProps, Page: CategoryPage })<P>;
|
export default WithLayout({ getData: getPageProps, Page: CategoryPage })<"P">;
|
||||||
export const dynamic = "force-static";
|
export const dynamic = "force-static";
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
import Page from "@calcom/features/ee/teams/pages/team-appearance-view";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("booking_appearance"),
|
||||||
|
(t) => t("appearance_team_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,10 @@
|
||||||
|
import Page from "@pages/settings/billing/index";
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("billing"),
|
||||||
|
(t) => t("team_billing_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
import Page from "@calcom/features/ee/teams/pages/team-members-view";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("team_members"),
|
||||||
|
(t) => t("members_team_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import LegacyPage, { GetLayout } from "@pages/settings/teams/[id]/onboard-members";
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("add_team_members"),
|
||||||
|
(t) => t("add_team_members_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default WithLayout({ Page: LegacyPage, getLayout: GetLayout })<"P">;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
import Page from "@calcom/features/ee/teams/pages/team-profile-view";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("profile"),
|
||||||
|
(t) => t("profile_team_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
import Page from "@calcom/features/ee/sso/page/teams-sso-view";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("sso_configuration"),
|
||||||
|
(t) => t("sso_configuration_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
|
||||||
|
|
||||||
|
export default WithLayout({ getLayout })<"L">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import LegacyPage, { LayoutWrapper } from "@pages/settings/teams/new/index";
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
import { WithLayout } from "app/layoutHOC";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("create_new_team"),
|
||||||
|
(t) => t("create_new_team_description")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default WithLayout({ Page: LegacyPage, getLayout: LayoutWrapper })<"P">;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { _generateMetadata } from "app/_utils";
|
||||||
|
|
||||||
|
import Page from "@calcom/features/ee/teams/pages/team-listing-view";
|
||||||
|
|
||||||
|
export const generateMetadata = async () =>
|
||||||
|
await _generateMetadata(
|
||||||
|
(t) => t("teams"),
|
||||||
|
(t) => t("create_manage_teams_collaborative")
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Page;
|
|
@ -3,12 +3,14 @@ import prismock from "../../../tests/libs/__mocks__/prisma";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
|
|
||||||
|
import { WEBSITE_URL } from "@calcom/lib/constants";
|
||||||
import type { MembershipRole, Prisma } from "@calcom/prisma/client";
|
import type { MembershipRole, Prisma } from "@calcom/prisma/client";
|
||||||
import { RedirectType } from "@calcom/prisma/enums";
|
import { RedirectType } from "@calcom/prisma/enums";
|
||||||
import type { teamMetadataSchema } from "@calcom/prisma/zod-utils";
|
import type { teamMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||||
|
|
||||||
import { moveTeamToOrg, moveUserToOrg, removeTeamFromOrg, removeUserFromOrg } from "./orgMigration";
|
import { moveTeamToOrg, moveUserToOrg, removeTeamFromOrg, removeUserFromOrg } from "./orgMigration";
|
||||||
|
|
||||||
|
const WEBSITE_PROTOCOL = new URL(WEBSITE_URL).protocol;
|
||||||
describe("orgMigration", () => {
|
describe("orgMigration", () => {
|
||||||
describe("moveUserToOrg", () => {
|
describe("moveUserToOrg", () => {
|
||||||
describe("when user email does not match orgAutoAcceptEmail", () => {
|
describe("when user email does not match orgAutoAcceptEmail", () => {
|
||||||
|
@ -1372,7 +1374,7 @@ async function expectRedirectToBeEnabled({
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(redirect).not.toBeNull();
|
expect(redirect).not.toBeNull();
|
||||||
expect(redirect?.toUrl).toBe(`http://${orgSlug}.cal.local:3000/${to}`);
|
expect(redirect?.toUrl).toBe(`${WEBSITE_PROTOCOL}//${orgSlug}.cal.local:3000/${to}`);
|
||||||
if (!redirect) {
|
if (!redirect) {
|
||||||
throw new Error(`Redirect doesn't exist for ${JSON.stringify(tempOrgRedirectWhere)}`);
|
throw new Error(`Redirect doesn't exist for ${JSON.stringify(tempOrgRedirectWhere)}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,48 +486,24 @@ export default function Success(props: SuccessProps) {
|
||||||
<div className="mt-3 font-medium">{t("where")}</div>
|
<div className="mt-3 font-medium">{t("where")}</div>
|
||||||
<div className="col-span-2 mt-3" data-testid="where">
|
<div className="col-span-2 mt-3" data-testid="where">
|
||||||
{!rescheduleLocation || locationToDisplay === rescheduleLocationToDisplay ? (
|
{!rescheduleLocation || locationToDisplay === rescheduleLocationToDisplay ? (
|
||||||
locationToDisplay.startsWith("http") ? (
|
<DisplayLocation
|
||||||
<a
|
locationToDisplay={locationToDisplay}
|
||||||
href={locationToDisplay}
|
providerName={providerName}
|
||||||
target="_blank"
|
/>
|
||||||
title={locationToDisplay}
|
|
||||||
className="text-default flex items-center gap-2"
|
|
||||||
rel="noreferrer">
|
|
||||||
{providerName || "Link"}
|
|
||||||
<ExternalLink className="text-default inline h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
locationToDisplay
|
|
||||||
)
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{!!formerTime &&
|
{!!formerTime && (
|
||||||
(locationToDisplay.startsWith("http") ? (
|
<DisplayLocation
|
||||||
<a
|
locationToDisplay={locationToDisplay}
|
||||||
href={locationToDisplay}
|
providerName={providerName}
|
||||||
target="_blank"
|
className="line-through"
|
||||||
title={locationToDisplay}
|
/>
|
||||||
className="text-default flex items-center gap-2 line-through"
|
|
||||||
rel="noreferrer">
|
|
||||||
{providerName || "Link"}
|
|
||||||
<ExternalLink className="text-default inline h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<p className="line-through">{locationToDisplay}</p>
|
|
||||||
))}
|
|
||||||
{rescheduleLocationToDisplay.startsWith("http") ? (
|
|
||||||
<a
|
|
||||||
href={rescheduleLocationToDisplay}
|
|
||||||
target="_blank"
|
|
||||||
title={rescheduleLocationToDisplay}
|
|
||||||
className="text-default flex items-center gap-2"
|
|
||||||
rel="noreferrer">
|
|
||||||
{rescheduleProviderName || "Link"}
|
|
||||||
<ExternalLink className="text-default inline h-4 w-4" />
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
rescheduleLocationToDisplay
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<DisplayLocation
|
||||||
|
locationToDisplay={rescheduleLocationToDisplay}
|
||||||
|
providerName={rescheduleProviderName}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -830,6 +806,29 @@ export default function Success(props: SuccessProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DisplayLocation = ({
|
||||||
|
locationToDisplay,
|
||||||
|
providerName,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
locationToDisplay: string;
|
||||||
|
providerName?: string;
|
||||||
|
className?: string;
|
||||||
|
}) =>
|
||||||
|
locationToDisplay.startsWith("http") ? (
|
||||||
|
<a
|
||||||
|
href={locationToDisplay}
|
||||||
|
target="_blank"
|
||||||
|
title={locationToDisplay}
|
||||||
|
className={classNames("text-default flex items-center gap-2", className)}
|
||||||
|
rel="noreferrer">
|
||||||
|
{providerName || "Link"}
|
||||||
|
<ExternalLink className="text-default inline h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<p className={className}>{locationToDisplay}</p>
|
||||||
|
);
|
||||||
|
|
||||||
Success.isBookingPage = true;
|
Success.isBookingPage = true;
|
||||||
Success.PageWrapper = PageWrapper;
|
Success.PageWrapper = PageWrapper;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
import { useIntercom } from "@calcom/features/ee/support/lib/intercom/useIntercom";
|
import { useIntercom } from "@calcom/features/ee/support/lib/intercom/useIntercom";
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
import AddNewTeamMembers from "@calcom/features/ee/teams/components/AddNewTeamMembers";
|
import AddNewTeamMembers from "@calcom/features/ee/teams/components/AddNewTeamMembers";
|
||||||
|
@ -19,12 +21,13 @@ const OnboardTeamMembersPage = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
OnboardTeamMembersPage.getLayout = (page: React.ReactElement) => (
|
export const GetLayout = (page: React.ReactElement) => (
|
||||||
<WizardLayout currentStep={2} maxSteps={2}>
|
<WizardLayout currentStep={2} maxSteps={2}>
|
||||||
{page}
|
{page}
|
||||||
</WizardLayout>
|
</WizardLayout>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
OnboardTeamMembersPage.getLayout = GetLayout;
|
||||||
OnboardTeamMembersPage.PageWrapper = PageWrapper;
|
OnboardTeamMembersPage.PageWrapper = PageWrapper;
|
||||||
|
|
||||||
export default OnboardTeamMembersPage;
|
export default OnboardTeamMembersPage;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
import { CreateANewTeamForm } from "@calcom/features/ee/teams/components";
|
import { CreateANewTeamForm } from "@calcom/features/ee/teams/components";
|
||||||
|
@ -18,7 +20,7 @@ const CreateNewTeamPage = () => {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const LayoutWrapper = (page: React.ReactElement) => {
|
export const LayoutWrapper = (page: React.ReactElement) => {
|
||||||
return (
|
return (
|
||||||
<WizardLayout currentStep={1} maxSteps={2}>
|
<WizardLayout currentStep={1} maxSteps={2}>
|
||||||
{page}
|
{page}
|
||||||
|
|
|
@ -333,11 +333,14 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const videoReferences = bookingObj.references.filter((reference) => reference.type.includes("_video"));
|
||||||
|
const latestVideoReference = videoReferences[videoReferences.length - 1];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
meetingUrl: bookingObj.references[0].meetingUrl ?? "",
|
meetingUrl: latestVideoReference.meetingUrl ?? "",
|
||||||
...(typeof bookingObj.references[0].meetingPassword === "string" && {
|
...(typeof latestVideoReference.meetingPassword === "string" && {
|
||||||
meetingPassword: bookingObj.references[0].meetingPassword,
|
meetingPassword: latestVideoReference.meetingPassword,
|
||||||
}),
|
}),
|
||||||
booking: {
|
booking: {
|
||||||
...bookingObj,
|
...bookingObj,
|
||||||
|
|
|
@ -214,7 +214,7 @@ test.describe("Booking limits", () => {
|
||||||
await page.goto(slotUrl);
|
await page.goto(slotUrl);
|
||||||
await bookTimeSlot(page);
|
await bookTimeSlot(page);
|
||||||
|
|
||||||
await expect(page.getByTestId("booking-fail")).toBeVisible({ timeout: 1000 });
|
await expect(page.getByTestId("booking-fail")).toBeVisible({ timeout: 5000 });
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step(`month after booking`, async () => {
|
await test.step(`month after booking`, async () => {
|
||||||
|
@ -224,7 +224,9 @@ test.describe("Booking limits", () => {
|
||||||
await expect(page.getByTestId("day").nth(0)).toBeVisible({ timeout: 10_000 });
|
await expect(page.getByTestId("day").nth(0)).toBeVisible({ timeout: 10_000 });
|
||||||
|
|
||||||
// the month after we made bookings should have availability unless we hit a yearly limit
|
// the month after we made bookings should have availability unless we hit a yearly limit
|
||||||
await expect((await availableDays.count()) === 0).toBe(limitUnit === "year");
|
// TODO: Temporary fix for failing test. It passes locally but fails on CI.
|
||||||
|
// See #13097
|
||||||
|
// await expect((await availableDays.count()) === 0).toBe(limitUnit === "year");
|
||||||
});
|
});
|
||||||
|
|
||||||
// increment date by unit after hitting each limit
|
// increment date by unit after hitting each limit
|
||||||
|
|
|
@ -751,7 +751,7 @@ export async function makePaymentUsingStripe(page: Page) {
|
||||||
const stripeFrame = stripeElement.frameLocator("iframe").first();
|
const stripeFrame = stripeElement.frameLocator("iframe").first();
|
||||||
await stripeFrame.locator('[name="number"]').fill("4242 4242 4242 4242");
|
await stripeFrame.locator('[name="number"]').fill("4242 4242 4242 4242");
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
await stripeFrame.locator('[name="expiry"]').fill(`${now.getMonth()} / ${now.getFullYear() + 1}`);
|
await stripeFrame.locator('[name="expiry"]').fill(`${now.getMonth() + 1} / ${now.getFullYear() + 1}`);
|
||||||
await stripeFrame.locator('[name="cvc"]').fill("111");
|
await stripeFrame.locator('[name="cvc"]').fill("111");
|
||||||
const postcalCodeIsVisible = await stripeFrame.locator('[name="postalCode"]').isVisible();
|
const postcalCodeIsVisible = await stripeFrame.locator('[name="postalCode"]').isVisible();
|
||||||
if (postcalCodeIsVisible) {
|
if (postcalCodeIsVisible) {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import type { TestFunction } from "vitest";
|
import type { TestFunction } from "vitest";
|
||||||
|
|
||||||
|
import { WEBSITE_URL } from "@calcom/lib/constants";
|
||||||
import { test } from "@calcom/web/test/fixtures/fixtures";
|
import { test } from "@calcom/web/test/fixtures/fixtures";
|
||||||
import type { Fixtures } from "@calcom/web/test/fixtures/fixtures";
|
import type { Fixtures } from "@calcom/web/test/fixtures/fixtures";
|
||||||
import { createOrganization } from "@calcom/web/test/utils/bookingScenario/bookingScenario";
|
import { createOrganization } from "@calcom/web/test/utils/bookingScenario/bookingScenario";
|
||||||
|
|
||||||
|
const WEBSITE_PROTOCOL = new URL(WEBSITE_URL).protocol;
|
||||||
const _testWithAndWithoutOrg = (
|
const _testWithAndWithoutOrg = (
|
||||||
description: Parameters<typeof testWithAndWithoutOrg>[0],
|
description: Parameters<typeof testWithAndWithoutOrg>[0],
|
||||||
fn: Parameters<typeof testWithAndWithoutOrg>[1],
|
fn: Parameters<typeof testWithAndWithoutOrg>[1],
|
||||||
|
@ -28,7 +30,7 @@ const _testWithAndWithoutOrg = (
|
||||||
skip,
|
skip,
|
||||||
org: {
|
org: {
|
||||||
organization: org,
|
organization: org,
|
||||||
urlOrigin: `http://${org.slug}.cal.local:3000`,
|
urlOrigin: `${WEBSITE_PROTOCOL}//${org.slug}.cal.local:3000`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -553,11 +553,18 @@ export default function RouteBuilder({
|
||||||
<SingleForm
|
<SingleForm
|
||||||
form={form}
|
form={form}
|
||||||
appUrl={appUrl}
|
appUrl={appUrl}
|
||||||
Page={({ hookForm, form }) => (
|
Page={({ hookForm, form }) => {
|
||||||
|
// If hookForm hasn't been initialized, don't render anything
|
||||||
|
// This is important here because some states get initialized which aren't reset when the hookForm is reset with the form values and they don't get the updated values
|
||||||
|
if (!hookForm.getValues().id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
<div className="route-config">
|
<div className="route-config">
|
||||||
<Routes hookForm={hookForm} appUrl={appUrl} form={form} />
|
<Routes hookForm={hookForm} appUrl={appUrl} form={form} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,9 @@ import { useBrandColors } from "./utils/use-brand-colors";
|
||||||
|
|
||||||
const loadFramerFeatures = () => import("./framer-features").then((res) => res.default);
|
const loadFramerFeatures = () => import("./framer-features").then((res) => res.default);
|
||||||
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy"));
|
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy"));
|
||||||
const UnpublishedEntity = dynamic(() => import("@calcom/ui").then((mod) => mod.UnpublishedEntity));
|
const UnpublishedEntity = dynamic(() =>
|
||||||
|
import("@calcom/ui/components/unpublished-entity/UnpublishedEntity").then((mod) => mod.UnpublishedEntity)
|
||||||
|
);
|
||||||
const DatePicker = dynamic(() => import("./components/DatePicker").then((mod) => mod.DatePicker), {
|
const DatePicker = dynamic(() => import("./components/DatePicker").then((mod) => mod.DatePicker), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,9 +15,12 @@ import { useBookerStore } from "../store";
|
||||||
import { FromToTime } from "../utils/dates";
|
import { FromToTime } from "../utils/dates";
|
||||||
import { useEvent } from "../utils/event";
|
import { useEvent } from "../utils/event";
|
||||||
|
|
||||||
const TimezoneSelect = dynamic(() => import("@calcom/ui").then((mod) => mod.TimezoneSelect), {
|
const TimezoneSelect = dynamic(
|
||||||
|
() => import("@calcom/ui/components/form/timezone-select/TimezoneSelect").then((mod) => mod.TimezoneSelect),
|
||||||
|
{
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const EventMeta = () => {
|
export const EventMeta = () => {
|
||||||
const { setTimezone, timeFormat, timezone } = useTimePreferences();
|
const { setTimezone, timeFormat, timezone } = useTimePreferences();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Prisma } from "@prisma/client";
|
import type { Prisma } from "@prisma/client";
|
||||||
import type { IncomingMessage } from "http";
|
import type { IncomingMessage } from "http";
|
||||||
|
|
||||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
import { IS_PRODUCTION, WEBSITE_URL } from "@calcom/lib/constants";
|
||||||
import { ALLOWED_HOSTNAMES, RESERVED_SUBDOMAINS, WEBAPP_URL } from "@calcom/lib/constants";
|
import { ALLOWED_HOSTNAMES, RESERVED_SUBDOMAINS, WEBAPP_URL } from "@calcom/lib/constants";
|
||||||
import logger from "@calcom/lib/logger";
|
import logger from "@calcom/lib/logger";
|
||||||
import slugify from "@calcom/lib/slugify";
|
import slugify from "@calcom/lib/slugify";
|
||||||
|
@ -100,9 +100,10 @@ export function subdomainSuffix() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOrgFullOrigin(slug: string, options: { protocol: boolean } = { protocol: true }) {
|
export function getOrgFullOrigin(slug: string, options: { protocol: boolean } = { protocol: true }) {
|
||||||
if (!slug) return options.protocol ? WEBAPP_URL : WEBAPP_URL.replace("https://", "").replace("http://", "");
|
if (!slug)
|
||||||
|
return options.protocol ? WEBSITE_URL : WEBSITE_URL.replace("https://", "").replace("http://", "");
|
||||||
const orgFullOrigin = `${
|
const orgFullOrigin = `${
|
||||||
options.protocol ? `${new URL(WEBAPP_URL).protocol}//` : ""
|
options.protocol ? `${new URL(WEBSITE_URL).protocol}//` : ""
|
||||||
}${slug}.${subdomainSuffix()}`;
|
}${slug}.${subdomainSuffix()}`;
|
||||||
return orgFullOrigin;
|
return orgFullOrigin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
|
|
@ -107,9 +107,7 @@ export default function TeamListItem(props: Props) {
|
||||||
<span className="text-default text-sm font-bold">{team.name}</span>
|
<span className="text-default text-sm font-bold">{team.name}</span>
|
||||||
<span className="text-muted block text-xs">
|
<span className="text-muted block text-xs">
|
||||||
{team.slug ? (
|
{team.slug ? (
|
||||||
`${getTeamUrlSync({ orgSlug: team.parent ? team.parent.slug : null, teamSlug: team.slug })}/${
|
`${getTeamUrlSync({ orgSlug: team.parent ? team.parent.slug : null, teamSlug: team.slug })}`
|
||||||
team.slug
|
|
||||||
}`
|
|
||||||
) : (
|
) : (
|
||||||
<Badge>{t("upgrade")}</Badge>
|
<Badge>{t("upgrade")}</Badge>
|
||||||
)}
|
)}
|
||||||
|
@ -245,11 +243,10 @@ export default function TeamListItem(props: Props) {
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigator.clipboard.writeText(
|
navigator.clipboard.writeText(
|
||||||
`${
|
`${getTeamUrlSync({
|
||||||
orgBranding
|
orgSlug: team.parent ? team.parent.slug : null,
|
||||||
? `${orgBranding.fullDomain}`
|
teamSlug: team.slug,
|
||||||
: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/team`
|
})}`
|
||||||
}/${team.slug}`
|
|
||||||
);
|
);
|
||||||
showToast(t("link_copied"), "success");
|
showToast(t("link_copied"), "success");
|
||||||
}}
|
}}
|
||||||
|
@ -285,11 +282,10 @@ export default function TeamListItem(props: Props) {
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
type="button"
|
type="button"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={`${
|
href={`${getTeamUrlSync({
|
||||||
orgBranding
|
orgSlug: team.parent ? team.parent.slug : null,
|
||||||
? `${orgBranding.fullDomain}`
|
teamSlug: team.slug,
|
||||||
: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/team`
|
})}`}
|
||||||
}/${team.slug}`}
|
|
||||||
StartIcon={ExternalLink}>
|
StartIcon={ExternalLink}>
|
||||||
{t("preview_team") as string}
|
{t("preview_team") as string}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { Meta } from "@calcom/ui";
|
import { Meta } from "@calcom/ui";
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import type { Prisma } from "@prisma/client";
|
import type { Prisma } from "@prisma/client";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
"./components/icon": "./components/icon/index.ts",
|
"./components/icon": "./components/icon/index.ts",
|
||||||
"./components/icon/Discord": "./components/icon/Discord.tsx",
|
"./components/icon/Discord": "./components/icon/Discord.tsx",
|
||||||
"./components/icon/SatSymbol": "./components/icon/SatSymbol.tsx",
|
"./components/icon/SatSymbol": "./components/icon/SatSymbol.tsx",
|
||||||
"./components/icon/Spinner": "./components/icon/Spinner.tsx"
|
"./components/icon/Spinner": "./components/icon/Spinner.tsx",
|
||||||
|
"./components/unpublished-entity/UnpublishedEntity": "./components/unpublished-entity/index.ts",
|
||||||
|
"./components/form/timezone-select/TimezoneSelect": "./components/form/timezone-select/index.ts"
|
||||||
},
|
},
|
||||||
"types": "./index.tsx",
|
"types": "./index.tsx",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
"cache": false
|
"cache": false
|
||||||
},
|
},
|
||||||
"dx": {
|
"dx": {
|
||||||
|
"dependsOn": ["//#env-check:common", "//#env-check:app-store"],
|
||||||
"cache": false
|
"cache": false
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user