fix: Provide calOrigin for organization embeds (#12380)

This commit is contained in:
Hariom Balhara 2023-11-27 23:08:27 +05:30 committed by GitHub
parent ada0ef242b
commit c9b50ffb78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 459 additions and 166 deletions

View File

@ -1,19 +1,337 @@
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { expect } from "@playwright/test"; import { expect } from "@playwright/test";
import { Linter } from "eslint";
import { parse } from "node-html-parser";
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
import { EMBED_LIB_URL, WEBAPP_URL } from "@calcom/lib/constants"; import { EMBED_LIB_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { MembershipRole } from "@calcom/prisma/client";
import { test } from "./lib/fixtures"; import { test } from "./lib/fixtures";
function chooseEmbedType(page: Page, embedType: string) { const linter = new Linter();
const eslintRules = {
"no-undef": "error",
"no-unused-vars": "off",
} as const;
test.describe.configure({ mode: "parallel" });
test.afterEach(({ users }) => users.deleteAll());
test.describe("Embed Code Generator Tests", () => {
test.describe("Non-Organization", () => {
test.beforeEach(async ({ users }) => {
const pro = await users.create();
await pro.apiLogin();
});
test.describe("Event Types Page", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/event-types");
});
test("open Embed Dialog and choose Inline for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "inline");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "inline",
basePage: "/event-types",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "inline",
orgSlug: null,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "inline",
orgSlug: null,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "inline",
calLink: `${pro.username}/30-min`,
});
});
test("open Embed Dialog and choose floating-popup for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "floating-popup");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "floating-popup",
basePage: "/event-types",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "floating-popup",
orgSlug: null,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "floating-popup",
orgSlug: null,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "floating-popup",
calLink: `${pro.username}/30-min`,
});
});
test("open Embed Dialog and choose element-click for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "element-click");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "element-click",
basePage: "/event-types",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "element-click",
orgSlug: null,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "element-click",
orgSlug: null,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "element-click",
calLink: `${pro.username}/30-min`,
});
});
});
test.describe("Event Type Edit Page", () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/event-types`);
await Promise.all([
page.locator('a[href*="/event-types/"]').first().click(),
page.waitForURL((url) => url.pathname.startsWith("/event-types/")),
]);
});
test("open Embed Dialog for the Event Type", async ({ page }) => {
const basePage = new URL(page.url()).pathname;
const embedUrl = await clickEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage,
});
chooseEmbedType(page, "inline");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
basePage,
embedType: "inline",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "inline",
orgSlug: null,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "inline",
calLink: decodeURIComponent(embedUrl),
});
});
});
});
test.describe("Organization", () => {
test.beforeEach(async ({ users, orgs }) => {
const org = await orgs.create({
name: "TestOrg",
});
const user = await users.create({
organizationId: org.id,
roleInOrganization: MembershipRole.MEMBER,
});
await user.apiLogin();
});
test.describe("Event Types Page", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/event-types");
});
test("open Embed Dialog and choose Inline for First Event Type", async ({ page, users }) => {
const [user] = users.get();
const { team: org } = await user.getOrgMembership();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "inline");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "inline",
basePage: "/event-types",
});
// Default tab is HTML code tab
await expectToContainValidCode(page, {
language: "html",
embedType: "inline",
orgSlug: org.slug,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "inline",
orgSlug: org.slug,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "inline",
calLink: `${user.username}/30-min`,
bookerUrl: getOrgFullOrigin(org?.slug ?? ""),
});
});
test("open Embed Dialog and choose floating-popup for First Event Type", async ({ page, users }) => {
const [user] = users.get();
const { team: org } = await user.getOrgMembership();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "floating-popup");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "floating-popup",
basePage: "/event-types",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "floating-popup",
orgSlug: org.slug,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "floating-popup",
orgSlug: org.slug,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "floating-popup",
calLink: `${user.username}/30-min`,
bookerUrl: getOrgFullOrigin(org?.slug ?? ""),
});
});
test("open Embed Dialog and choose element-click for First Event Type", async ({ page, users }) => {
const [user] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
const { team: org } = await user.getOrgMembership();
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "element-click");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "element-click",
basePage: "/event-types",
});
await expectToContainValidCode(page, {
language: "html",
embedType: "element-click",
orgSlug: org.slug,
});
await goToReactCodeTab(page);
await expectToContainValidCode(page, {
language: "react",
embedType: "element-click",
orgSlug: org.slug,
});
await goToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "element-click",
calLink: `${user.username}/30-min`,
bookerUrl: getOrgFullOrigin(org?.slug ?? ""),
});
});
});
});
});
type EmbedType = "inline" | "floating-popup" | "element-click";
function chooseEmbedType(page: Page, embedType: EmbedType) {
page.locator(`[data-testid=${embedType}]`).click(); page.locator(`[data-testid=${embedType}]`).click();
} }
async function gotToPreviewTab(page: Page) { async function goToPreviewTab(page: Page) {
// To prevent early timeouts // To prevent early timeouts
// eslint-disable-next-line playwright/no-wait-for-timeout // eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page.locator("[data-testid=embed-tabs]").locator("text=Preview").click(); await page.locator("[data-testid=horizontal-tab-Preview]").click();
}
async function goToReactCodeTab(page: Page) {
// To prevent early timeouts
// eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(1000);
await page.locator("[data-testid=horizontal-tab-React]").click();
} }
async function clickEmbedButton(page: Page) { async function clickEmbedButton(page: Page) {
@ -55,7 +373,7 @@ async function expectToBeNavigatingToEmbedCodeAndPreviewDialog(
basePage, basePage,
}: { }: {
embedUrl: string | null; embedUrl: string | null;
embedType: string; embedType: EmbedType;
basePage: string; basePage: string;
} }
) { ) {
@ -73,10 +391,108 @@ async function expectToBeNavigatingToEmbedCodeAndPreviewDialog(
}); });
} }
async function expectToContainValidCode(page: Page, { embedType }: { embedType: string }) { async function expectToContainValidCode(
page: Page,
{
embedType,
language,
orgSlug,
}: { embedType: EmbedType; language: "html" | "react"; orgSlug: string | null }
) {
if (language === "react") {
return expectValidReactEmbedSnippet(page, { embedType, orgSlug });
}
if (language === "html") {
return expectValidHtmlEmbedSnippet(page, { embedType, orgSlug });
}
throw new Error("Unknown language");
}
async function expectValidHtmlEmbedSnippet(
page: Page,
{ embedType, orgSlug }: { embedType: EmbedType; orgSlug: string | null }
) {
const embedCode = await page.locator("[data-testid=embed-code]").inputValue(); const embedCode = await page.locator("[data-testid=embed-code]").inputValue();
expect(embedCode.includes("(function (C, A, L)")).toBe(true); expect(embedCode).toContain("function (C, A, L)");
expect(embedCode.includes(`Cal ${embedType} embed code begins`)).toBe(true); expect(embedCode).toContain(`Cal ${embedType} embed code begins`);
if (orgSlug) {
expect(embedCode).toContain(orgSlug);
}
const dom = parse(embedCode);
const scripts = dom.getElementsByTagName("script");
assertThatCodeIsValidVanillaJsCode(scripts[0].innerText);
return {
message: () => `passed`,
pass: true,
};
}
function assertThatCodeIsValidVanillaJsCode(code: string) {
const lintResult = linter.verify(code, {
env: {
browser: true,
},
parserOptions: {
ecmaVersion: 2021,
},
globals: {
Cal: "readonly",
},
rules: eslintRules,
});
if (lintResult.length) {
console.log(
JSON.stringify({
lintResult,
code,
})
);
}
expect(lintResult.length).toBe(0);
}
function assertThatCodeIsValidReactCode(code: string) {
const lintResult = linter.verify(code, {
env: {
browser: true,
},
parserOptions: {
ecmaVersion: 2021,
ecmaFeatures: {
jsx: true,
},
sourceType: "module",
},
rules: eslintRules,
});
if (lintResult.length) {
console.log(
JSON.stringify({
lintResult,
code,
})
);
}
expect(lintResult.length).toBe(0);
}
async function expectValidReactEmbedSnippet(
page: Page,
{ embedType, orgSlug }: { embedType: EmbedType; orgSlug: string | null }
) {
const embedCode = await page.locator("[data-testid=embed-react]").inputValue();
expect(embedCode).toContain("export default function MyApp(");
expect(embedCode).toContain(
embedType === "floating-popup" ? "floatingButton" : embedType === "inline" ? `<Cal` : "data-cal-link"
);
if (orgSlug) {
expect(embedCode).toContain(orgSlug);
}
assertThatCodeIsValidReactCode(embedCode);
return { return {
message: () => `passed`, message: () => `passed`,
pass: true, pass: true,
@ -88,141 +504,10 @@ async function expectToContainValidCode(page: Page, { embedType }: { embedType:
*/ */
async function expectToContainValidPreviewIframe( async function expectToContainValidPreviewIframe(
page: Page, page: Page,
{ embedType, calLink }: { embedType: string; calLink: string } { embedType, calLink, bookerUrl }: { embedType: EmbedType; calLink: string; bookerUrl?: string }
) { ) {
const bookerUrl = `${WEBAPP_URL}`; bookerUrl = bookerUrl || `${WEBAPP_URL}`;
expect(await page.locator("[data-testid=embed-preview]").getAttribute("src")).toContain( expect(await page.locator("[data-testid=embed-preview]").getAttribute("src")).toContain(
`/preview.html?embedType=${embedType}&calLink=${calLink}&embedLibUrl=${EMBED_LIB_URL}&bookerUrl=${bookerUrl}` `/preview.html?embedType=${embedType}&calLink=${calLink}&embedLibUrl=${EMBED_LIB_URL}&bookerUrl=${bookerUrl}`
); );
} }
test.describe.configure({ mode: "parallel" });
test.afterEach(({ users }) => users.deleteAll());
test.describe("Embed Code Generator Tests", () => {
test.beforeEach(async ({ users }) => {
const pro = await users.create();
await pro.apiLogin();
});
test.describe("Event Types Page", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/event-types");
});
test("open Embed Dialog and choose Inline for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "inline");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "inline",
basePage: "/event-types",
});
await expectToContainValidCode(page, { embedType: "inline" });
await gotToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "inline",
calLink: `${pro.username}/30-min`,
});
});
test("open Embed Dialog and choose floating-popup for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "floating-popup");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "floating-popup",
basePage: "/event-types",
});
await expectToContainValidCode(page, { embedType: "floating-popup" });
await gotToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "floating-popup",
calLink: `${pro.username}/30-min`,
});
});
test("open Embed Dialog and choose element-click for First Event Type", async ({ page, users }) => {
const [pro] = users.get();
const embedUrl = await clickFirstEventTypeEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage: "/event-types",
});
chooseEmbedType(page, "element-click");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
embedType: "element-click",
basePage: "/event-types",
});
await expectToContainValidCode(page, { embedType: "element-click" });
await gotToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "element-click",
calLink: `${pro.username}/30-min`,
});
});
});
test.describe("Event Type Edit Page", () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/event-types`);
await Promise.all([
page.locator('a[href*="/event-types/"]').first().click(),
page.waitForURL((url) => url.pathname.startsWith("/event-types/")),
]);
});
test("open Embed Dialog for the Event Type", async ({ page }) => {
const basePage = new URL(page.url()).pathname;
const embedUrl = await clickEmbedButton(page);
await expectToBeNavigatingToEmbedTypesDialog(page, {
embedUrl,
basePage,
});
chooseEmbedType(page, "inline");
await expectToBeNavigatingToEmbedCodeAndPreviewDialog(page, {
embedUrl,
basePage,
embedType: "inline",
});
await expectToContainValidCode(page, {
embedType: "inline",
});
await gotToPreviewTab(page);
await expectToContainValidPreviewIframe(page, {
embedType: "inline",
calLink: decodeURIComponent(embedUrl),
});
});
});
});

View File

@ -460,7 +460,7 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => {
} }
return membership; return membership;
}, },
getOrg: async () => { getOrgMembership: async () => {
return prisma.membership.findFirstOrThrow({ return prisma.membership.findFirstOrThrow({
where: { where: {
userId: user.id, userId: user.id,
@ -471,7 +471,13 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => {
}, },
}, },
}, },
include: { team: { select: { children: true, metadata: true, name: true } } }, include: {
team: {
include: {
children: true,
},
},
},
}); });
}, },
getFirstEventAsOwner: async () => getFirstEventAsOwner: async () =>

View File

@ -168,7 +168,7 @@ test.describe("Teams - NonOrg", () => {
await expect(page.locator("[data-testid=alert]")).toBeVisible(); await expect(page.locator("[data-testid=alert]")).toBeVisible();
// cleanup // cleanup
const org = await owner.getOrg(); const org = await owner.getOrgMembership();
await prisma.team.delete({ where: { id: org.teamId } }); await prisma.team.delete({ where: { id: org.teamId } });
} }
}); });

View File

@ -45,7 +45,7 @@ test.describe("Unpublished", () => {
test("Organization profile", async ({ users, page }) => { test("Organization profile", async ({ users, page }) => {
const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true }); const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true });
const { team: org } = await owner.getOrg(); const { team: org } = await owner.getOrgMembership();
const { requestedSlug } = org.metadata as { requestedSlug: string }; const { requestedSlug } = org.metadata as { requestedSlug: string };
await page.goto(`/org/${requestedSlug}`); await page.goto(`/org/${requestedSlug}`);
await page.waitForLoadState("networkidle"); await page.waitForLoadState("networkidle");
@ -62,7 +62,7 @@ test.describe("Unpublished", () => {
isOrg: true, isOrg: true,
hasSubteam: true, hasSubteam: true,
}); });
const { team: org } = await owner.getOrg(); const { team: org } = await owner.getOrgMembership();
const { requestedSlug } = org.metadata as { requestedSlug: string }; const { requestedSlug } = org.metadata as { requestedSlug: string };
const [{ slug: subteamSlug }] = org.children as { slug: string }[]; const [{ slug: subteamSlug }] = org.children as { slug: string }[];
await page.goto(`/org/${requestedSlug}/team/${subteamSlug}`); await page.goto(`/org/${requestedSlug}/team/${subteamSlug}`);
@ -80,7 +80,7 @@ test.describe("Unpublished", () => {
isOrg: true, isOrg: true,
hasSubteam: true, hasSubteam: true,
}); });
const { team: org } = await owner.getOrg(); const { team: org } = await owner.getOrgMembership();
const { requestedSlug } = org.metadata as { requestedSlug: string }; const { requestedSlug } = org.metadata as { requestedSlug: string };
const [{ slug: subteamSlug, id: subteamId }] = org.children as { slug: string; id: number }[]; const [{ slug: subteamSlug, id: subteamId }] = org.children as { slug: string; id: number }[];
const { slug: subteamEventSlug } = await owner.getFirstTeamEvent(subteamId); const { slug: subteamEventSlug } = await owner.getFirstTeamEvent(subteamId);
@ -95,7 +95,7 @@ test.describe("Unpublished", () => {
test("Organization user", async ({ users, page }) => { test("Organization user", async ({ users, page }) => {
const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true }); const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true });
const { team: org } = await owner.getOrg(); const { team: org } = await owner.getOrgMembership();
const { requestedSlug } = org.metadata as { requestedSlug: string }; const { requestedSlug } = org.metadata as { requestedSlug: string };
await page.goto(`/org/${requestedSlug}/${owner.username}`); await page.goto(`/org/${requestedSlug}/${owner.username}`);
await page.waitForLoadState("networkidle"); await page.waitForLoadState("networkidle");
@ -107,7 +107,7 @@ test.describe("Unpublished", () => {
test("Organization user event-type", async ({ users, page }) => { test("Organization user event-type", async ({ users, page }) => {
const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true }); const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true });
const { team: org } = await owner.getOrg(); const { team: org } = await owner.getOrgMembership();
const { requestedSlug } = org.metadata as { requestedSlug: string }; const { requestedSlug } = org.metadata as { requestedSlug: string };
const [{ slug: ownerEventType }] = owner.eventTypes; const [{ slug: ownerEventType }] = owner.eventTypes;
await page.goto(`/org/${requestedSlug}/${owner.username}/${ownerEventType}`); await page.goto(`/org/${requestedSlug}/${owner.username}/${ownerEventType}`);

View File

@ -104,10 +104,9 @@ function generateFiles() {
* If a file has index.ts or index.tsx, it can be imported after removing the index.ts* part * If a file has index.ts or index.tsx, it can be imported after removing the index.ts* part
*/ */
function getModulePath(path: string, moduleName: string) { function getModulePath(path: string, moduleName: string) {
return ( return `./${path.replace(/\\/g, "/")}/${moduleName
`./${path.replace(/\\/g, "/")}/` + .replace(/\/index\.ts|\/index\.tsx/, "")
moduleName.replace(/\/index\.ts|\/index\.tsx/, "").replace(/\.tsx$|\.ts$/, "") .replace(/\.tsx$|\.ts$/, "")}`;
);
} }
type ImportConfig = type ImportConfig =

View File

@ -1,9 +1,15 @@
import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import { CAL_URL, IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
import type { PreviewState } from "../types"; import type { PreviewState } from "../types";
import { embedLibUrl } from "./constants"; import { embedLibUrl } from "./constants";
import { getDimension } from "./getDimension"; import { getDimension } from "./getDimension";
export const doWeNeedCalOriginProp = (embedCalOrigin: string) => {
// If we are self hosted, calOrigin won't be app.cal.com so we need to pass it
// If we are not self hosted but it's still different from WEBAPP_URL and CAL_URL, we need to pass it -> It happens for organization booking URL at the moment
return IS_SELF_HOSTED || (embedCalOrigin !== WEBAPP_URL && embedCalOrigin !== CAL_URL);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export const Codes = { export const Codes = {
react: { react: {
@ -33,13 +39,9 @@ export const Codes = {
return <Cal return <Cal
calLink="${calLink}" calLink="${calLink}"
style={{width:"${width}",height:"${height}",overflow:"scroll"}} style={{width:"${width}",height:"${height}",overflow:"scroll"}}
${previewState.layout ? `config={{layout: '${previewState.layout}'}}` : ""}${ ${previewState.layout ? `config={{layout: '${previewState.layout}'}}` : ""}
IS_SELF_HOSTED ${doWeNeedCalOriginProp(embedCalOrigin) ? ` calOrigin="${embedCalOrigin}"` : ""}
? ` ${IS_SELF_HOSTED ? `calJsUrl="${embedLibUrl}"` : ""}
calOrigin="${embedCalOrigin}"
calJsUrl="${embedLibUrl}"`
: ""
}
/>; />;
};`; };`;
}, },
@ -53,7 +55,7 @@ export const Codes = {
return code` return code`
import { getCalApi } from "@calcom/embed-react"; import { getCalApi } from "@calcom/embed-react";
import { useEffect } from "react"; import { useEffect } from "react";
export default function App() { export default function MyApp() {
useEffect(()=>{ useEffect(()=>{
(async function () { (async function () {
const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""}); const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""});
@ -77,7 +79,7 @@ export const Codes = {
return code` return code`
import { getCalApi } from "@calcom/embed-react"; import { getCalApi } from "@calcom/embed-react";
import { useEffect } from "react"; import { useEffect } from "react";
export default function App() { export default function MyApp() {
useEffect(()=>{ useEffect(()=>{
(async function () { (async function () {
const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""}); const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""});
@ -85,7 +87,8 @@ export const Codes = {
})(); })();
}, []) }, [])
return <button return <button
data-cal-link="${calLink}"${IS_SELF_HOSTED ? `\ndata-cal-origin="${embedCalOrigin}"` : ""} data-cal-link="${calLink}"
${doWeNeedCalOriginProp(embedCalOrigin) ? ` data-cal-origin="${embedCalOrigin}"` : ""}
${`data-cal-config='${JSON.stringify({ ${`data-cal-config='${JSON.stringify({
layout: previewState.layout, layout: previewState.layout,
})}'`} })}'`}

View File

@ -2,14 +2,14 @@ import { forwardRef } from "react";
import type { MutableRefObject } from "react"; import type { MutableRefObject } from "react";
import type { BookerLayout } from "@calcom/features/bookings/Booker/types"; import type { BookerLayout } from "@calcom/features/bookings/Booker/types";
import { APP_NAME, IS_SELF_HOSTED } from "@calcom/lib/constants"; import { APP_NAME } from "@calcom/lib/constants";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl"; import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { TextArea } from "@calcom/ui"; import { TextArea } from "@calcom/ui";
import { Code, Trello } from "@calcom/ui/components/icon"; import { Code, Trello } from "@calcom/ui/components/icon";
import type { EmbedType, PreviewState, EmbedFramework } from "../types"; import type { EmbedType, PreviewState, EmbedFramework } from "../types";
import { Codes } from "./EmbedCodes"; import { Codes, doWeNeedCalOriginProp } from "./EmbedCodes";
import { EMBED_PREVIEW_HTML_URL, embedLibUrl } from "./constants"; import { EMBED_PREVIEW_HTML_URL, embedLibUrl } from "./constants";
import { getDimension } from "./getDimension"; import { getDimension } from "./getDimension";
import { useEmbedCalOrigin } from "./hooks"; import { useEmbedCalOrigin } from "./hooks";
@ -193,7 +193,7 @@ const getEmbedTypeSpecificString = ({
} else if (embedType === "floating-popup") { } else if (embedType === "floating-popup") {
const floatingButtonArg = { const floatingButtonArg = {
calLink, calLink,
...(IS_SELF_HOSTED ? { calOrigin: embedCalOrigin } : null), ...(doWeNeedCalOriginProp(embedCalOrigin) ? { calOrigin: embedCalOrigin } : null),
...previewState.floatingPopup, ...previewState.floatingPopup,
}; };
return frameworkCodes[embedType]({ return frameworkCodes[embedType]({