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:
Amit Sharma
2024-07-04 09:54:35 +05:30
committed by GitHub
co-authored by Keith Williams Anik Dhabal Babu
parent c3a532cff0
commit 557498b80d
3 changed files with 119 additions and 104 deletions
+21 -16
View File
@@ -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
+93 -83
View File
@@ -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>
+5 -5
View File
@@ -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}