feat: embed: remove "Preview" tab and instead split code/preview layout 50/50 vertically (#15492)
* feat: embed: remove "Preview" tab and instead split code/preview layout 50/50 vertically * fix: use single preview tab * fix e2e * add border radius * final e2e fix * fix: don't show preview tab component --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
co-authored by
Keith Williams
Anik Dhabal Babu
parent
c3a532cff0
commit
557498b80d
@@ -59,8 +59,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: null,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "inline",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
@@ -96,7 +97,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: null,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "floating-popup",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
@@ -132,7 +135,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: null,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "element-click",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
@@ -170,8 +175,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: null,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "inline",
|
||||
calLink: decodeURIComponent(embedUrl),
|
||||
@@ -227,7 +233,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: org.slug,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "inline",
|
||||
calLink: `${user.username}/30-min`,
|
||||
@@ -266,7 +274,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: org.slug,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "floating-popup",
|
||||
calLink: `${user.username}/30-min`,
|
||||
@@ -304,7 +314,9 @@ test.describe("Embed Code Generator Tests", () => {
|
||||
orgSlug: org.slug,
|
||||
});
|
||||
|
||||
await goToPreviewTab(page);
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "element-click",
|
||||
calLink: `${user.username}/30-min`,
|
||||
@@ -320,13 +332,6 @@ function chooseEmbedType(page: Page, embedType: EmbedType) {
|
||||
page.locator(`[data-testid=${embedType}]`).click();
|
||||
}
|
||||
|
||||
async function goToPreviewTab(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-Preview]").click();
|
||||
}
|
||||
|
||||
async function goToReactCodeTab(page: Page) {
|
||||
// To prevent early timeouts
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
|
||||
@@ -715,6 +715,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
label: "Bottom left",
|
||||
},
|
||||
];
|
||||
const previewTab = tabs.find((tab) => tab.name === "Preview");
|
||||
|
||||
return (
|
||||
<DialogContent
|
||||
@@ -723,7 +724,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
className="rounded-lg p-0.5 sm:max-w-[80rem]"
|
||||
type="creation">
|
||||
<div className="flex">
|
||||
<div className="bg-muted flex h-[90vh] w-1/3 flex-col overflow-y-auto p-8">
|
||||
<div className="bg-muted flex h-[95vh] w-1/3 flex-col overflow-y-auto p-8">
|
||||
<h3
|
||||
className="text-emphasis mb-2.5 flex items-center text-xl font-semibold leading-5"
|
||||
id="modal-title">
|
||||
@@ -1020,100 +1021,109 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex w-2/3 flex-col px-8 pt-8">
|
||||
<div className="flex h-[95vh] w-2/3 flex-col px-8 pt-8">
|
||||
<HorizontalTabs
|
||||
data-testid="embed-tabs"
|
||||
tabs={embedType === "email" ? parsedTabs.filter((tab) => tab.name === "Preview") : parsedTabs}
|
||||
tabs={
|
||||
embedType === "email"
|
||||
? parsedTabs.filter((tab) => tab.name === "Preview")
|
||||
: parsedTabs.filter((tab) => tab.name !== "Preview")
|
||||
}
|
||||
linkShallow
|
||||
/>
|
||||
{tabs.map((tab) => {
|
||||
if (embedType !== "email") {
|
||||
return (
|
||||
<div
|
||||
key={tab.href}
|
||||
className={classNames(
|
||||
searchParams?.get("embedTabName") === tab.href.split("=")[1]
|
||||
? "flex flex-grow flex-col"
|
||||
: "hidden"
|
||||
)}>
|
||||
<div className="flex h-[55vh] flex-grow flex-col">
|
||||
{tab.type === "code" ? (
|
||||
<tab.Component
|
||||
namespace={namespace}
|
||||
embedType={embedType}
|
||||
calLink={calLink}
|
||||
previewState={previewState}
|
||||
ref={refOfEmbedCodesRefs.current[tab.name]}
|
||||
<>
|
||||
<div className="flex h-full flex-col">
|
||||
{tabs.map((tab) => {
|
||||
if (embedType !== "email") {
|
||||
if (tab.name === "Preview") return null;
|
||||
return (
|
||||
<div
|
||||
key={tab.href}
|
||||
className={classNames(
|
||||
searchParams?.get("embedTabName") === tab.href.split("=")[1] ? "flex-1" : "hidden"
|
||||
)}>
|
||||
{tab.type === "code" && (
|
||||
<tab.Component
|
||||
namespace={namespace}
|
||||
embedType={embedType}
|
||||
calLink={calLink}
|
||||
previewState={previewState}
|
||||
ref={refOfEmbedCodesRefs.current[tab.name]}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
searchParams?.get("embedTabName") === "embed-preview" ? "mt-2 block" : "hidden"
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<tab.Component
|
||||
namespace={namespace}
|
||||
embedType={embedType}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (embedType === "email" && (tab.name !== "Preview" || !eventTypeData?.eventType)) return;
|
||||
|
||||
return (
|
||||
<div key={tab.href} className={classNames("flex flex-grow flex-col")}>
|
||||
<div className="flex h-[55vh] flex-grow flex-col">
|
||||
<EmailEmbedPreview
|
||||
calLink={calLink}
|
||||
previewState={previewState}
|
||||
ref={iframeRef}
|
||||
eventType={eventTypeData?.eventType}
|
||||
emailContentRef={emailContentRef}
|
||||
username={teamSlug ?? (data?.user.username as string)}
|
||||
month={month as string}
|
||||
selectedDateAndTime={
|
||||
selectedDatesAndTimes
|
||||
? selectedDatesAndTimes[eventTypeData?.eventType.slug as string]
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
searchParams?.get("embedTabName") === "embed-preview" ? "mt-2 block" : "hidden"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
searchParams?.get("embedTabName") === "embed-preview" ? "mt-2 block" : "hidden"
|
||||
}
|
||||
/>
|
||||
<DialogFooter className="mt-10 flex-row-reverse gap-x-2" showDivider>
|
||||
<DialogClose />
|
||||
{tab.type === "code" ? (
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={() => {
|
||||
const currentTabCodeEl = refOfEmbedCodesRefs.current[tab.name].current;
|
||||
if (!currentTabCodeEl) {
|
||||
return;
|
||||
}
|
||||
navigator.clipboard.writeText(currentTabCodeEl.value);
|
||||
showToast(t("code_copied"), "success");
|
||||
}}>
|
||||
{t("copy_code")}
|
||||
</Button>
|
||||
) : null}
|
||||
</DialogFooter>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
})}
|
||||
|
||||
if (embedType === "email" && (tab.name !== "Preview" || !eventTypeData?.eventType)) return;
|
||||
|
||||
return (
|
||||
<div key={tab.href} className={classNames("flex flex-grow flex-col")}>
|
||||
<div className="flex h-[55vh] flex-grow flex-col">
|
||||
<EmailEmbedPreview
|
||||
{embedType !== "email" && previewTab && (
|
||||
<div className="flex-1">
|
||||
<previewTab.Component
|
||||
namespace={namespace}
|
||||
embedType={embedType}
|
||||
calLink={calLink}
|
||||
eventType={eventTypeData?.eventType}
|
||||
emailContentRef={emailContentRef}
|
||||
username={teamSlug ?? (data?.user.username as string)}
|
||||
month={month as string}
|
||||
selectedDateAndTime={
|
||||
selectedDatesAndTimes
|
||||
? selectedDatesAndTimes[eventTypeData?.eventType.slug as string]
|
||||
: {}
|
||||
}
|
||||
previewState={previewState}
|
||||
ref={iframeRef}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={searchParams?.get("embedTabName") === "embed-preview" ? "mt-2 block" : "hidden"}
|
||||
/>
|
||||
<DialogFooter className="mt-10 flex-row-reverse gap-x-2" showDivider>
|
||||
<DialogClose />
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleCopyEmailText();
|
||||
}}>
|
||||
{embedType === "email" ? t("copy") : t("copy_code")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
)}
|
||||
</div>
|
||||
<DialogFooter className="mt-10 flex-row-reverse gap-x-2" showDivider>
|
||||
<DialogClose />
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={() => {
|
||||
if (embedType === "email") {
|
||||
handleCopyEmailText();
|
||||
} else {
|
||||
const currentTabHref = searchParams?.get("embedTabName");
|
||||
const currentTabName = tabs.find(
|
||||
(tab) => tab.href === `embedTabName=${currentTabHref}`
|
||||
)?.name;
|
||||
if (!currentTabName) return;
|
||||
const currentTabCodeEl = refOfEmbedCodesRefs.current[currentTabName].current;
|
||||
if (!currentTabCodeEl) {
|
||||
return;
|
||||
}
|
||||
navigator.clipboard.writeText(currentTabCodeEl.value);
|
||||
showToast(t("code_copied"), "success");
|
||||
}
|
||||
}}>
|
||||
{embedType === "email" ? t("copy") : t("copy_code")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
||||
@@ -36,7 +36,7 @@ export const tabs = [
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<small className="text-subtle flex py-4">
|
||||
<small className="text-subtle flex py-2">
|
||||
{t("place_where_cal_widget_appear", { appName: APP_NAME })}
|
||||
</small>
|
||||
</div>
|
||||
@@ -91,7 +91,7 @@ export const tabs = [
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<small className="text-subtle flex py-4">{t("create_update_react_component")}</small>
|
||||
<small className="text-subtle flex py-2">{t("create_update_react_component")}</small>
|
||||
<TextArea
|
||||
data-testid="embed-react"
|
||||
ref={ref as typeof ref & MutableRefObject<HTMLTextAreaElement>}
|
||||
@@ -100,10 +100,10 @@ export const tabs = [
|
||||
readOnly
|
||||
style={{ resize: "none", overflow: "auto" }}
|
||||
value={`/* First make sure that you have installed the package */
|
||||
|
||||
|
||||
/* If you are using yarn */
|
||||
// yarn add @calcom/embed-react
|
||||
|
||||
|
||||
/* If you are using npm */
|
||||
// npm install @calcom/embed-react
|
||||
${getEmbedTypeSpecificString({
|
||||
@@ -141,7 +141,7 @@ export const tabs = [
|
||||
<iframe
|
||||
ref={ref as typeof ref & MutableRefObject<HTMLIFrameElement>}
|
||||
data-testid="embed-preview"
|
||||
className="h-[100vh] border"
|
||||
className="rounded-md border"
|
||||
width="100%"
|
||||
height="100%"
|
||||
src={iframeSrc}
|
||||
|
||||
Reference in New Issue
Block a user