fix: Enhance the Robustness of Embed Snippets for Multiple Embeds on a Single Page (#11512)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com>
This commit is contained in:
parent
fcb443a8eb
commit
a9fcd900cd
|
@ -322,6 +322,7 @@ function EventTypeSingleLayout({
|
||||||
StartIcon={Code}
|
StartIcon={Code}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
variant="icon"
|
variant="icon"
|
||||||
|
namespace={eventType.slug}
|
||||||
tooltip={t("embed")}
|
tooltip={t("embed")}
|
||||||
tooltipSide="bottom"
|
tooltipSide="bottom"
|
||||||
tooltipOffset={4}
|
tooltipOffset={4}
|
||||||
|
|
|
@ -507,6 +507,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||||
{!isManagedEventType && (
|
{!isManagedEventType && (
|
||||||
<DropdownMenuItem className="outline-none">
|
<DropdownMenuItem className="outline-none">
|
||||||
<EventTypeEmbedButton
|
<EventTypeEmbedButton
|
||||||
|
namespace={type.slug}
|
||||||
as={DropdownItem}
|
as={DropdownItem}
|
||||||
type="button"
|
type="button"
|
||||||
StartIcon={Code}
|
StartIcon={Code}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { CAL_URL } from "@calcom/lib/constants";
|
||||||
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
|
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
|
||||||
|
import slugify from "@calcom/lib/slugify";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
import type { ButtonProps } from "@calcom/ui";
|
import type { ButtonProps } from "@calcom/ui";
|
||||||
import {
|
import {
|
||||||
|
@ -434,6 +435,8 @@ export const FormAction = forwardRef(function FormAction<T extends typeof Button
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
embedUrl: embedLink,
|
embedUrl: embedLink,
|
||||||
|
// We are okay with namespace clashing here if just in case names clash
|
||||||
|
namespace: slugify((routingForm?.name || "").substring(0, 5)),
|
||||||
},
|
},
|
||||||
edit: {
|
edit: {
|
||||||
href: `${appUrl}/form-edit/${routingForm?.id}`,
|
href: `${appUrl}/form-edit/${routingForm?.id}`,
|
||||||
|
|
|
@ -13,12 +13,13 @@ type CalProps = {
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
uiDebug?: boolean;
|
uiDebug?: boolean;
|
||||||
};
|
};
|
||||||
|
namespace?: string;
|
||||||
config?: PrefillAndIframeAttrsConfig;
|
config?: PrefillAndIframeAttrsConfig;
|
||||||
embedJsUrl?: string;
|
embedJsUrl?: string;
|
||||||
} & React.HTMLAttributes<HTMLDivElement>;
|
} & React.HTMLAttributes<HTMLDivElement>;
|
||||||
|
|
||||||
const Cal = function Cal(props: CalProps) {
|
const Cal = function Cal(props: CalProps) {
|
||||||
const { calLink, calOrigin, config, initConfig = {}, embedJsUrl, ...restProps } = props;
|
const { calLink, calOrigin, namespace = "", config, initConfig = {}, embedJsUrl, ...restProps } = props;
|
||||||
if (!calLink) {
|
if (!calLink) {
|
||||||
throw new Error("calLink is required");
|
throw new Error("calLink is required");
|
||||||
}
|
}
|
||||||
|
@ -31,16 +32,28 @@ const Cal = function Cal(props: CalProps) {
|
||||||
}
|
}
|
||||||
initializedRef.current = true;
|
initializedRef.current = true;
|
||||||
const element = ref.current;
|
const element = ref.current;
|
||||||
Cal("init", {
|
if (namespace) {
|
||||||
...initConfig,
|
Cal("init", namespace, {
|
||||||
origin: calOrigin,
|
...initConfig,
|
||||||
});
|
origin: calOrigin,
|
||||||
Cal("inline", {
|
});
|
||||||
elementOrSelector: element,
|
Cal.ns[namespace]("inline", {
|
||||||
calLink,
|
elementOrSelector: element,
|
||||||
config,
|
calLink,
|
||||||
});
|
config,
|
||||||
}, [Cal, calLink, config, calOrigin, initConfig]);
|
});
|
||||||
|
} else {
|
||||||
|
Cal("init", {
|
||||||
|
...initConfig,
|
||||||
|
origin: calOrigin,
|
||||||
|
});
|
||||||
|
Cal("inline", {
|
||||||
|
elementOrSelector: element,
|
||||||
|
calLink,
|
||||||
|
config,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [Cal, calLink, config, namespace, calOrigin, initConfig]);
|
||||||
|
|
||||||
if (!Cal) {
|
if (!Cal) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -498,12 +498,14 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||||
embedType,
|
embedType,
|
||||||
embedUrl,
|
embedUrl,
|
||||||
tabs,
|
tabs,
|
||||||
|
namespace,
|
||||||
eventTypeHideOptionDisabled,
|
eventTypeHideOptionDisabled,
|
||||||
types,
|
types,
|
||||||
}: {
|
}: {
|
||||||
embedType: EmbedType;
|
embedType: EmbedType;
|
||||||
embedUrl: string;
|
embedUrl: string;
|
||||||
tabs: EmbedTabs;
|
tabs: EmbedTabs;
|
||||||
|
namespace: string;
|
||||||
eventTypeHideOptionDisabled: boolean;
|
eventTypeHideOptionDisabled: boolean;
|
||||||
types: EmbedTypes;
|
types: EmbedTypes;
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -1009,6 +1011,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||||
<div className="flex h-[55vh] flex-grow flex-col">
|
<div className="flex h-[55vh] flex-grow flex-col">
|
||||||
{tab.type === "code" ? (
|
{tab.type === "code" ? (
|
||||||
<tab.Component
|
<tab.Component
|
||||||
|
namespace={namespace}
|
||||||
embedType={embedType}
|
embedType={embedType}
|
||||||
calLink={calLink}
|
calLink={calLink}
|
||||||
previewState={previewState}
|
previewState={previewState}
|
||||||
|
@ -1016,6 +1019,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<tab.Component
|
<tab.Component
|
||||||
|
namespace={namespace}
|
||||||
embedType={embedType}
|
embedType={embedType}
|
||||||
calLink={calLink}
|
calLink={calLink}
|
||||||
previewState={previewState}
|
previewState={previewState}
|
||||||
|
@ -1097,7 +1101,8 @@ export const EmbedDialog = ({
|
||||||
eventTypeHideOptionDisabled: boolean;
|
eventTypeHideOptionDisabled: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const searchParams = useCompatSearchParams();
|
const searchParams = useCompatSearchParams();
|
||||||
const embedUrl = searchParams?.get("embedUrl") as string;
|
const embedUrl = (searchParams?.get("embedUrl") || "") as string;
|
||||||
|
const namespace = (searchParams?.get("namespace") || "") as string;
|
||||||
return (
|
return (
|
||||||
<Dialog name="embed" clearQueryParamsOnClose={queryParamsForDialog}>
|
<Dialog name="embed" clearQueryParamsOnClose={queryParamsForDialog}>
|
||||||
{!searchParams?.get("embedType") ? (
|
{!searchParams?.get("embedType") ? (
|
||||||
|
@ -1106,6 +1111,7 @@ export const EmbedDialog = ({
|
||||||
<EmbedTypeCodeAndPreviewDialogContent
|
<EmbedTypeCodeAndPreviewDialogContent
|
||||||
embedType={searchParams?.get("embedType") as EmbedType}
|
embedType={searchParams?.get("embedType") as EmbedType}
|
||||||
embedUrl={embedUrl}
|
embedUrl={embedUrl}
|
||||||
|
namespace={namespace}
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
types={types}
|
types={types}
|
||||||
eventTypeHideOptionDisabled={eventTypeHideOptionDisabled}
|
eventTypeHideOptionDisabled={eventTypeHideOptionDisabled}
|
||||||
|
@ -1117,6 +1123,7 @@ export const EmbedDialog = ({
|
||||||
|
|
||||||
type EmbedButtonProps<T> = {
|
type EmbedButtonProps<T> = {
|
||||||
embedUrl: string;
|
embedUrl: string;
|
||||||
|
namespace: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
as?: T;
|
as?: T;
|
||||||
|
@ -1129,6 +1136,7 @@ export const EmbedButton = <T extends React.ElementType>({
|
||||||
className = "",
|
className = "",
|
||||||
as,
|
as,
|
||||||
eventId,
|
eventId,
|
||||||
|
namespace,
|
||||||
...props
|
...props
|
||||||
}: EmbedButtonProps<T> & React.ComponentPropsWithoutRef<T>) => {
|
}: EmbedButtonProps<T> & React.ComponentPropsWithoutRef<T>) => {
|
||||||
const { goto } = useRouterHelpers();
|
const { goto } = useRouterHelpers();
|
||||||
|
@ -1137,6 +1145,7 @@ export const EmbedButton = <T extends React.ElementType>({
|
||||||
goto({
|
goto({
|
||||||
dialog: "embed",
|
dialog: "embed",
|
||||||
eventId: eventId ? eventId.toString() : "",
|
eventId: eventId ? eventId.toString() : "",
|
||||||
|
namespace,
|
||||||
embedUrl,
|
embedUrl,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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 { getApiName } from "./getApiName";
|
||||||
import { getDimension } from "./getDimension";
|
import { getDimension } from "./getDimension";
|
||||||
|
|
||||||
export const doWeNeedCalOriginProp = (embedCalOrigin: string) => {
|
export const doWeNeedCalOriginProp = (embedCalOrigin: string) => {
|
||||||
|
@ -18,14 +19,17 @@ export const Codes = {
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
previewState,
|
previewState,
|
||||||
embedCalOrigin,
|
embedCalOrigin,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
calLink: string;
|
calLink: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
previewState: PreviewState;
|
previewState: PreviewState;
|
||||||
embedCalOrigin: string;
|
embedCalOrigin: string;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
const width = getDimension(previewState.inline.width);
|
const width = getDimension(previewState.inline.width);
|
||||||
const height = getDimension(previewState.inline.height);
|
const height = getDimension(previewState.inline.height);
|
||||||
|
const namespaceProp = `${namespace ? `namespace="${namespace}"` : ""}`;
|
||||||
return code`
|
return code`
|
||||||
import Cal, { getCalApi } from "@calcom/embed-react";
|
import Cal, { getCalApi } from "@calcom/embed-react";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
@ -36,21 +40,23 @@ export const Codes = {
|
||||||
${uiInstructionCode}
|
${uiInstructionCode}
|
||||||
})();
|
})();
|
||||||
}, [])
|
}, [])
|
||||||
return <Cal
|
return <Cal ${namespaceProp}
|
||||||
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}'}}` : ""}
|
||||||
${doWeNeedCalOriginProp(embedCalOrigin) ? ` calOrigin="${embedCalOrigin}"` : ""}
|
${doWeNeedCalOriginProp(embedCalOrigin) ? ` calOrigin="${embedCalOrigin}"` : ""}
|
||||||
${IS_SELF_HOSTED ? `calJsUrl="${embedLibUrl}"` : ""}
|
${IS_SELF_HOSTED ? `embedJsUrl="${embedLibUrl}"` : ""}
|
||||||
/>;
|
/>;
|
||||||
};`;
|
};`;
|
||||||
},
|
},
|
||||||
"floating-popup": ({
|
"floating-popup": ({
|
||||||
floatingButtonArg,
|
floatingButtonArg,
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
floatingButtonArg: string;
|
floatingButtonArg: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
return code`
|
return code`
|
||||||
import { getCalApi } from "@calcom/embed-react";
|
import { getCalApi } from "@calcom/embed-react";
|
||||||
|
@ -59,7 +65,7 @@ export const Codes = {
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
(async function () {
|
(async function () {
|
||||||
const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""});
|
const cal = await getCalApi(${IS_SELF_HOSTED ? `"${embedLibUrl}"` : ""});
|
||||||
cal("floatingButton", ${floatingButtonArg});
|
${getApiName({ namespace, mainApiName: "cal" })}("floatingButton", ${floatingButtonArg});
|
||||||
${uiInstructionCode}
|
${uiInstructionCode}
|
||||||
})();
|
})();
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -70,11 +76,13 @@ export const Codes = {
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
previewState,
|
previewState,
|
||||||
embedCalOrigin,
|
embedCalOrigin,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
calLink: string;
|
calLink: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
previewState: PreviewState;
|
previewState: PreviewState;
|
||||||
embedCalOrigin: string;
|
embedCalOrigin: string;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
return code`
|
return code`
|
||||||
import { getCalApi } from "@calcom/embed-react";
|
import { getCalApi } from "@calcom/embed-react";
|
||||||
|
@ -86,7 +94,7 @@ export const Codes = {
|
||||||
${uiInstructionCode}
|
${uiInstructionCode}
|
||||||
})();
|
})();
|
||||||
}, [])
|
}, [])
|
||||||
return <button
|
return <button data-cal-namespace="${namespace}"
|
||||||
data-cal-link="${calLink}"
|
data-cal-link="${calLink}"
|
||||||
${doWeNeedCalOriginProp(embedCalOrigin) ? ` data-cal-origin="${embedCalOrigin}"` : ""}
|
${doWeNeedCalOriginProp(embedCalOrigin) ? ` data-cal-origin="${embedCalOrigin}"` : ""}
|
||||||
${`data-cal-config='${JSON.stringify({
|
${`data-cal-config='${JSON.stringify({
|
||||||
|
@ -101,12 +109,14 @@ export const Codes = {
|
||||||
calLink,
|
calLink,
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
previewState,
|
previewState,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
calLink: string;
|
calLink: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
previewState: PreviewState;
|
previewState: PreviewState;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
return code`Cal("inline", {
|
return code`${getApiName({ namespace })}("inline", {
|
||||||
elementOrSelector:"#my-cal-inline",
|
elementOrSelector:"#my-cal-inline",
|
||||||
calLink: "${calLink}",
|
calLink: "${calLink}",
|
||||||
layout: "${previewState.layout}"
|
layout: "${previewState.layout}"
|
||||||
|
@ -118,25 +128,30 @@ export const Codes = {
|
||||||
"floating-popup": ({
|
"floating-popup": ({
|
||||||
floatingButtonArg,
|
floatingButtonArg,
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
floatingButtonArg: string;
|
floatingButtonArg: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
return code`Cal("floatingButton", ${floatingButtonArg});
|
return code`${getApiName({ namespace, mainApiName: "Cal" })}("floatingButton", ${floatingButtonArg});
|
||||||
${uiInstructionCode}`;
|
${uiInstructionCode}`;
|
||||||
},
|
},
|
||||||
"element-click": ({
|
"element-click": ({
|
||||||
calLink,
|
calLink,
|
||||||
uiInstructionCode,
|
uiInstructionCode,
|
||||||
previewState,
|
previewState,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
calLink: string;
|
calLink: string;
|
||||||
uiInstructionCode: string;
|
uiInstructionCode: string;
|
||||||
previewState: PreviewState;
|
previewState: PreviewState;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
return code`
|
return code`
|
||||||
// Important: Please add following attributes to the element you want to open Cal on click
|
// Important: Please add the following attributes to the element that should trigger the calendar to open upon clicking.
|
||||||
// \`data-cal-link="${calLink}"\`
|
// \`data-cal-link="${calLink}"\`
|
||||||
|
// data-cal-namespace="${namespace}"
|
||||||
// \`data-cal-config='${JSON.stringify({
|
// \`data-cal-config='${JSON.stringify({
|
||||||
layout: previewState.layout,
|
layout: previewState.layout,
|
||||||
})}'\`
|
})}'\`
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { Code, Trello } from "@calcom/ui/components/icon";
|
||||||
import type { EmbedType, PreviewState, EmbedFramework } from "../types";
|
import type { EmbedType, PreviewState, EmbedFramework } from "../types";
|
||||||
import { Codes, doWeNeedCalOriginProp } from "./EmbedCodes";
|
import { Codes, doWeNeedCalOriginProp } from "./EmbedCodes";
|
||||||
import { EMBED_PREVIEW_HTML_URL, embedLibUrl } from "./constants";
|
import { EMBED_PREVIEW_HTML_URL, embedLibUrl } from "./constants";
|
||||||
|
import { getApiName } from "./getApiName";
|
||||||
import { getDimension } from "./getDimension";
|
import { getDimension } from "./getDimension";
|
||||||
import { useEmbedCalOrigin } from "./hooks";
|
import { useEmbedCalOrigin } from "./hooks";
|
||||||
|
|
||||||
|
@ -22,10 +23,10 @@ export const tabs = [
|
||||||
type: "code",
|
type: "code",
|
||||||
Component: forwardRef<
|
Component: forwardRef<
|
||||||
HTMLTextAreaElement | HTMLIFrameElement | null,
|
HTMLTextAreaElement | HTMLIFrameElement | null,
|
||||||
{ embedType: EmbedType; calLink: string; previewState: PreviewState }
|
{ embedType: EmbedType; calLink: string; previewState: PreviewState; namespace: string }
|
||||||
>(function EmbedHtml({ embedType, calLink, previewState }, ref) {
|
>(function EmbedHtml({ embedType, calLink, previewState, namespace }, ref) {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const embedSnippetString = useGetEmbedSnippetString();
|
const embedSnippetString = useGetEmbedSnippetString(namespace);
|
||||||
const embedCalOrigin = useEmbedCalOrigin();
|
const embedCalOrigin = useEmbedCalOrigin();
|
||||||
if (ref instanceof Function || !ref) {
|
if (ref instanceof Function || !ref) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -55,7 +56,14 @@ export const tabs = [
|
||||||
: ""
|
: ""
|
||||||
}<script type="text/javascript">
|
}<script type="text/javascript">
|
||||||
${embedSnippetString}
|
${embedSnippetString}
|
||||||
${getEmbedTypeSpecificString({ embedFramework: "HTML", embedType, calLink, previewState, embedCalOrigin })}
|
${getEmbedTypeSpecificString({
|
||||||
|
embedFramework: "HTML",
|
||||||
|
embedType,
|
||||||
|
calLink,
|
||||||
|
previewState,
|
||||||
|
embedCalOrigin,
|
||||||
|
namespace,
|
||||||
|
})}
|
||||||
</script>
|
</script>
|
||||||
<!-- Cal ${embedType} embed code ends -->`}
|
<!-- Cal ${embedType} embed code ends -->`}
|
||||||
/>
|
/>
|
||||||
|
@ -71,8 +79,8 @@ export const tabs = [
|
||||||
type: "code",
|
type: "code",
|
||||||
Component: forwardRef<
|
Component: forwardRef<
|
||||||
HTMLTextAreaElement | HTMLIFrameElement | null,
|
HTMLTextAreaElement | HTMLIFrameElement | null,
|
||||||
{ embedType: EmbedType; calLink: string; previewState: PreviewState }
|
{ embedType: EmbedType; calLink: string; previewState: PreviewState; namespace: string }
|
||||||
>(function EmbedReact({ embedType, calLink, previewState }, ref) {
|
>(function EmbedReact({ embedType, calLink, previewState, namespace }, ref) {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const embedCalOrigin = useEmbedCalOrigin();
|
const embedCalOrigin = useEmbedCalOrigin();
|
||||||
|
|
||||||
|
@ -99,7 +107,14 @@ export const tabs = [
|
||||||
|
|
||||||
/* If you are using npm */
|
/* If you are using npm */
|
||||||
// npm install @calcom/embed-react
|
// npm install @calcom/embed-react
|
||||||
${getEmbedTypeSpecificString({ embedFramework: "react", embedType, calLink, previewState, embedCalOrigin })}
|
${getEmbedTypeSpecificString({
|
||||||
|
embedFramework: "react",
|
||||||
|
embedType,
|
||||||
|
calLink,
|
||||||
|
previewState,
|
||||||
|
embedCalOrigin,
|
||||||
|
namespace,
|
||||||
|
})}
|
||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -113,7 +128,7 @@ export const tabs = [
|
||||||
type: "iframe",
|
type: "iframe",
|
||||||
Component: forwardRef<
|
Component: forwardRef<
|
||||||
HTMLIFrameElement | HTMLTextAreaElement | null,
|
HTMLIFrameElement | HTMLTextAreaElement | null,
|
||||||
{ calLink: string; embedType: EmbedType; previewState: PreviewState }
|
{ calLink: string; embedType: EmbedType; previewState: PreviewState; namespace: string }
|
||||||
>(function Preview({ calLink, embedType }, ref) {
|
>(function Preview({ calLink, embedType }, ref) {
|
||||||
const bookerUrl = useBookerUrl();
|
const bookerUrl = useBookerUrl();
|
||||||
const iframeSrc = `${EMBED_PREVIEW_HTML_URL}?embedType=${embedType}&calLink=${calLink}&embedLibUrl=${embedLibUrl}&bookerUrl=${bookerUrl}`;
|
const iframeSrc = `${EMBED_PREVIEW_HTML_URL}?embedType=${embedType}&calLink=${calLink}&embedLibUrl=${embedLibUrl}&bookerUrl=${bookerUrl}`;
|
||||||
|
@ -144,12 +159,14 @@ const getEmbedTypeSpecificString = ({
|
||||||
calLink,
|
calLink,
|
||||||
embedCalOrigin,
|
embedCalOrigin,
|
||||||
previewState,
|
previewState,
|
||||||
|
namespace,
|
||||||
}: {
|
}: {
|
||||||
embedFramework: EmbedFramework;
|
embedFramework: EmbedFramework;
|
||||||
embedType: EmbedType;
|
embedType: EmbedType;
|
||||||
calLink: string;
|
calLink: string;
|
||||||
previewState: PreviewState;
|
previewState: PreviewState;
|
||||||
embedCalOrigin: string;
|
embedCalOrigin: string;
|
||||||
|
namespace: string;
|
||||||
}) => {
|
}) => {
|
||||||
const frameworkCodes = Codes[embedFramework];
|
const frameworkCodes = Codes[embedFramework];
|
||||||
if (!frameworkCodes) {
|
if (!frameworkCodes) {
|
||||||
|
@ -165,7 +182,7 @@ const getEmbedTypeSpecificString = ({
|
||||||
};
|
};
|
||||||
if (embedFramework === "react") {
|
if (embedFramework === "react") {
|
||||||
uiInstructionStringArg = {
|
uiInstructionStringArg = {
|
||||||
apiName: "cal",
|
apiName: getApiName({ namespace, mainApiName: "cal" }),
|
||||||
theme: previewState.theme,
|
theme: previewState.theme,
|
||||||
brandColor: previewState.palette.brandColor,
|
brandColor: previewState.palette.brandColor,
|
||||||
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
||||||
|
@ -173,7 +190,7 @@ const getEmbedTypeSpecificString = ({
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
uiInstructionStringArg = {
|
uiInstructionStringArg = {
|
||||||
apiName: "Cal",
|
apiName: getApiName({ namespace, mainApiName: "Cal" }),
|
||||||
theme: previewState.theme,
|
theme: previewState.theme,
|
||||||
brandColor: previewState.palette.brandColor,
|
brandColor: previewState.palette.brandColor,
|
||||||
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
||||||
|
@ -189,6 +206,7 @@ const getEmbedTypeSpecificString = ({
|
||||||
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
||||||
previewState,
|
previewState,
|
||||||
embedCalOrigin,
|
embedCalOrigin,
|
||||||
|
namespace,
|
||||||
});
|
});
|
||||||
} else if (embedType === "floating-popup") {
|
} else if (embedType === "floating-popup") {
|
||||||
const floatingButtonArg = {
|
const floatingButtonArg = {
|
||||||
|
@ -197,11 +215,13 @@ const getEmbedTypeSpecificString = ({
|
||||||
...previewState.floatingPopup,
|
...previewState.floatingPopup,
|
||||||
};
|
};
|
||||||
return frameworkCodes[embedType]({
|
return frameworkCodes[embedType]({
|
||||||
|
namespace,
|
||||||
floatingButtonArg: JSON.stringify(floatingButtonArg),
|
floatingButtonArg: JSON.stringify(floatingButtonArg),
|
||||||
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
||||||
});
|
});
|
||||||
} else if (embedType === "element-click") {
|
} else if (embedType === "element-click") {
|
||||||
return frameworkCodes[embedType]({
|
return frameworkCodes[embedType]({
|
||||||
|
namespace,
|
||||||
calLink,
|
calLink,
|
||||||
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
uiInstructionCode: getEmbedUIInstructionString(uiInstructionStringArg),
|
||||||
previewState,
|
previewState,
|
||||||
|
@ -253,10 +273,10 @@ const getInstructionString = ({
|
||||||
return `${apiName}("${instructionName}", ${JSON.stringify(instructionArg)});`;
|
return `${apiName}("${instructionName}", ${JSON.stringify(instructionArg)});`;
|
||||||
};
|
};
|
||||||
|
|
||||||
function useGetEmbedSnippetString() {
|
function useGetEmbedSnippetString(namespace: string | null) {
|
||||||
const bookerUrl = useBookerUrl();
|
const bookerUrl = useBookerUrl();
|
||||||
// TODO: Import this string from @calcom/embed-snippet
|
// TODO: Import this string from @calcom/embed-snippet
|
||||||
return `(function (C, A, L) { let p = function (a, ar) { a.q.push(ar); }; let d = C.document; C.Cal = C.Cal || function () { let cal = C.Cal; let ar = arguments; if (!cal.loaded) { cal.ns = {}; cal.q = cal.q || []; d.head.appendChild(d.createElement("script")).src = A; cal.loaded = true; } if (ar[0] === L) { const api = function () { p(api, arguments); }; const namespace = ar[1]; api.q = api.q || []; typeof namespace === "string" ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar); return; } p(cal, ar); }; })(window, "${embedLibUrl}", "init");
|
return `(function (C, A, L) { let p = function (a, ar) { a.q.push(ar); }; let d = C.document; C.Cal = C.Cal || function () { let cal = C.Cal; let ar = arguments; if (!cal.loaded) { cal.ns = {}; cal.q = cal.q || []; d.head.appendChild(d.createElement("script")).src = A; cal.loaded = true; } if (ar[0] === L) { const api = function () { p(api, arguments); }; const namespace = ar[1]; api.q = api.q || []; typeof namespace === "string" ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar); return; } p(cal, ar); }; })(window, "${embedLibUrl}", "init");
|
||||||
Cal("init", {origin:"${bookerUrl}"});
|
Cal("init", ${namespace ? `"${namespace}",` : ""} {origin:"${bookerUrl}"});
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
export function getApiName({
|
||||||
|
namespace,
|
||||||
|
mainApiName = "Cal",
|
||||||
|
}: {
|
||||||
|
namespace: string | null;
|
||||||
|
mainApiName?: string;
|
||||||
|
}) {
|
||||||
|
if (!namespace) {
|
||||||
|
return mainApiName;
|
||||||
|
}
|
||||||
|
const isAValidVariableName = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(namespace);
|
||||||
|
// Try to use dot notation if possible because it's more readable otherwise use bracket notation
|
||||||
|
return isAValidVariableName ? `${mainApiName}.ns.${namespace}` : `${mainApiName}.ns["${namespace}"]`;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user