Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OPIK-759] implement side dialog component and log a trace dialog #1111

Merged
merged 3 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/opik-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/opik-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "1.1.0",
"@radix-ui/react-dialog": "^1.1.0",
"@radix-ui/react-dropdown-menu": "2.1.1",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "1.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,22 @@
import React, { useState } from "react";
import { FrameworkIntegration } from "./types";
import { Button } from "@/components/ui/button";
import { buildDocsUrl } from "@/lib/utils";
import { SquareArrowOutUpRight } from "lucide-react";
import ApiKeyCard from "../ApiKeyCard/ApiKeyCard";
import GoogleColabCard from "../GoogleColabCard/GoogleColabCard";
import IntegrationTemplate from "./IntegrationTemplate";
import usePluginsStore from "@/store/PluginsStore";
import FrameworkIntegrationsContent, {
FrameworkIntegrationsContentProps,
} from "./FrameworkIntegrationsContent";

type FrameworkIntegrationsProps = {
integrationList: FrameworkIntegration[];
apiKey?: string;
showColabLinks?: boolean;
};
const FrameworkIntegrations: React.FC<FrameworkIntegrationsProps> = ({
integrationList,
apiKey,
showColabLinks,
}) => {
const [integrationIndex, setIntegrationIndex] = useState<number>(0);
const integration = integrationList[integrationIndex];
export type FrameworkIntegrationsProps = Omit<
FrameworkIntegrationsContentProps,
"apiKey" | "showColabLinks"
>;
const FrameworkIntegrations: React.FC<FrameworkIntegrationsProps> = (props) => {
const FrameworkIntegrations = usePluginsStore(
(state) => state.FrameworkIntegrations,
);

return (
<div className="m-auto flex w-full max-w-[1250px] gap-6">
<div className="sticky top-20 flex w-[250px] shrink-0 flex-col gap-4 self-start">
<h4 className="comet-title-s">Select framework</h4>
<ul className="flex flex-col gap-2">
{integrationList.map((item, index) => (
<li
key={item.label}
className="comet-body-s flex h-10 w-full cursor-pointer items-center gap-2 rounded-md pl-2 pr-4 text-foreground hover:bg-primary-foreground data-[status=active]:bg-primary-100"
onClick={() => setIntegrationIndex(index)}
data-status={index === integrationIndex ? "active" : "inactive"}
>
<img
alt={item.label}
src={item.logo}
className="size-[32px] shrink-0"
/>
<div className="ml-1 truncate">{item.label}</div>
</li>
))}
</ul>
<Button className="w-fit pl-2" variant="ghost" asChild>
<a
href={buildDocsUrl("/tracing/integrations/overview")}
target="_blank"
rel="noreferrer"
>
Explore all integrations
<SquareArrowOutUpRight className="ml-2 size-4 shrink-0" />
</a>
</Button>
</div>
<div className="flex min-w-[650px] flex-1 gap-6">
<div className="flex w-full flex-1 flex-col">
<IntegrationTemplate code={integration.code} apiKey={apiKey} />
</div>
if (FrameworkIntegrations) {
return <FrameworkIntegrations {...props} />;
}

<div className="sticky top-20 flex w-[250px] shrink-0 flex-col gap-6 self-start">
{apiKey && <ApiKeyCard apiKey={apiKey} />}
{showColabLinks ? <GoogleColabCard link={integration.colab} /> : null}
</div>
</div>
</div>
);
return <FrameworkIntegrationsContent {...props} />;
};

export default FrameworkIntegrations;
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useState } from "react";
import { FrameworkIntegration } from "./types";
import { Button } from "@/components/ui/button";
import { buildDocsUrl } from "@/lib/utils";
import { SquareArrowOutUpRight } from "lucide-react";
import ApiKeyCard from "../ApiKeyCard/ApiKeyCard";
import GoogleColabCard from "../GoogleColabCard/GoogleColabCard";
import IntegrationTemplate from "./IntegrationTemplate";
import { QUICKSTART_INTEGRATIONS } from "./quickstart-integrations";
import { cn } from "@/lib/utils";

export type FrameworkIntegrationsContentProps = {
integrationList?: FrameworkIntegration[];
apiKey?: string;
showColabLinks?: boolean;
stickyOffset?: number;
};
const FrameworkIntegrationsContent: React.FC<
FrameworkIntegrationsContentProps
> = ({
integrationList = QUICKSTART_INTEGRATIONS,
apiKey,
showColabLinks,
stickyOffset = 0,
}) => {
const [integrationIndex, setIntegrationIndex] = useState<number>(0);
const integration = integrationList[integrationIndex];

const stickyOffsetStyle = `top-${stickyOffset}`;

return (
<div className="m-auto flex w-full max-w-[1250px] gap-6">
<div
className={cn(
"sticky flex w-[250px] shrink-0 flex-col gap-4 self-start",
stickyOffsetStyle,
)}
>
<h4 className="comet-title-s">Select framework</h4>
<ul className="flex flex-col gap-2">
{integrationList.map((item, index) => (
<li
key={item.label}
className="comet-body-s flex h-10 w-full cursor-pointer items-center gap-2 rounded-md pl-2 pr-4 text-foreground hover:bg-primary-foreground data-[status=active]:bg-primary-100"
onClick={() => setIntegrationIndex(index)}
data-status={index === integrationIndex ? "active" : "inactive"}
>
<img
alt={item.label}
src={item.logo}
className="size-[32px] shrink-0"
/>
<div className="ml-1 truncate">{item.label}</div>
</li>
))}
</ul>
<Button className="w-fit pl-2" variant="ghost" asChild>
<a
href={buildDocsUrl("/tracing/integrations/overview")}
target="_blank"
rel="noreferrer"
>
Explore all integrations
<SquareArrowOutUpRight className="ml-2 size-4 shrink-0" />
</a>
</Button>
</div>
<div className="flex min-w-[650px] flex-1 gap-6">
<div className="flex w-full flex-1 flex-col">
<IntegrationTemplate code={integration.code} apiKey={apiKey} />
</div>

<div
className={cn(
"sticky flex w-[250px] shrink-0 flex-col gap-6 self-start",
stickyOffsetStyle,
)}
>
{apiKey && <ApiKeyCard apiKey={apiKey} />}
{showColabLinks ? <GoogleColabCard link={integration.colab} /> : null}
</div>
</div>
</div>
);
};

export default FrameworkIntegrationsContent;
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ import React from "react";
import { Button } from "@/components/ui/button";
import { Link } from "@tanstack/react-router";
import useAppStore from "@/store/AppStore";
import { QUICKSTART_INTEGRATIONS } from "@/components/pages-shared/onboarding/FrameworkIntegrations/quickstart-integrations";
import FrameworkIntegrations from "@/components/pages-shared/onboarding/FrameworkIntegrations/FrameworkIntegrations";

type GetStartedProps = {
apiKey?: string;
showColabLinks?: boolean;
};

const GetStarted: React.FunctionComponent<GetStartedProps> = ({
apiKey,
showColabLinks = true,
}) => {
const GetStarted = () => {
const workspaceName = useAppStore((state) => state.activeWorkspaceName);

return (
Expand All @@ -28,11 +19,7 @@ const GetStarted: React.FunctionComponent<GetStartedProps> = ({
your code, or explore our ready-to-run examples on the right
</div>
</div>
<FrameworkIntegrations
integrationList={QUICKSTART_INTEGRATIONS}
apiKey={apiKey}
showColabLinks={showColabLinks}
/>
<FrameworkIntegrations />
<Button variant="link" className="mt-2" size="sm" asChild>
<Link to="/$workspaceName/home" params={{ workspaceName }}>
Skip, explore the platform on my own
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import React, { useState } from "react";
import { FlaskConical, InspectionPanel, MousePointer } from "lucide-react";
import useAppStore from "@/store/AppStore";
import { buildDocsUrl } from "@/lib/utils";
import SideDialog from "@/components/shared/SideDialog/SideDialog";
import FrameworkIntegrations from "@/components/pages-shared/onboarding/FrameworkIntegrations/FrameworkIntegrations";
import AddExperimentDialog from "../ExperimentsShared/AddExperimentDialog";
import { Link } from "@tanstack/react-router";

const GetStartedSection = () => {
const workspaceName = useAppStore((state) => state.activeWorkspaceName);
const [isNewExperimentDialogOpened, setIsNewExperimentDialogOpened] =
useState<boolean>(false);
const [isLogTraceDialogOpened, setIsLogTraceDialogOpened] = useState(false);

const openNewExperimentDialog = () => setIsNewExperimentDialogOpened(true);
const openLogTraceDialog = () => setIsLogTraceDialogOpened(true);

return (
<div>
Expand All @@ -22,17 +25,15 @@ const GetStartedSection = () => {
</div>
</div>
<div className="flex gap-x-4">
<a
href={buildDocsUrl("/tracing/log_traces")}
target="_blank"
rel="noreferrer"
<div
onClick={openLogTraceDialog}
className="flex w-full max-w-[300px] cursor-pointer items-center gap-3 rounded-md border bg-white p-4 transition-shadow hover:shadow-md"
>
<div className="flex size-[24px] items-center justify-center rounded bg-[#DAFBF0] ">
<InspectionPanel className="size-3.5 text-[#295747]" />
</div>
<div className="comet-body-s">Log a trace</div>
</a>
</div>
<div
onClick={openNewExperimentDialog}
className="flex w-full max-w-[300px] cursor-pointer items-center gap-3 rounded-md border bg-white p-4 transition-shadow hover:shadow-md"
Expand All @@ -52,12 +53,28 @@ const GetStartedSection = () => {
</div>
<div className="comet-body-s">Try out playground</div>
</Link>

<AddExperimentDialog
open={isNewExperimentDialogOpened}
setOpen={setIsNewExperimentDialogOpened}
/>
</div>

<SideDialog
open={isLogTraceDialogOpened}
setOpen={setIsLogTraceDialogOpened}
>
<div className="flex w-full min-w-fit flex-col pb-12">
<div className="pb-8">
<h1 className="comet-title-l text-center">Log a trace</h1>
<div className="comet-body-s m-auto mt-4 w-[468px] self-center text-center text-muted-slate">
Select a framework and follow the instructions to integrate Comet
with your code, or explore our ready-to-run examples on the right
</div>
</div>
<FrameworkIntegrations />
</div>
</SideDialog>

<AddExperimentDialog
open={isNewExperimentDialogOpened}
setOpen={setIsNewExperimentDialogOpened}
/>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,8 @@ import { useRouter } from "@tanstack/react-router";
import { MoveLeft } from "lucide-react";
import { Button } from "@/components/ui/button";
import FrameworkIntegrations from "@/components/pages-shared/onboarding/FrameworkIntegrations/FrameworkIntegrations";
import { QUICKSTART_INTEGRATIONS } from "@/components/pages-shared/onboarding/FrameworkIntegrations/quickstart-integrations";

type QuickstartProps = {
apiKey?: string;
showColabLinks?: boolean;
};

const Quickstart: React.FunctionComponent<QuickstartProps> = ({
apiKey,
showColabLinks = true,
}) => {
const Quickstart = () => {
const router = useRouter();

return (
Expand All @@ -39,11 +30,7 @@ const Quickstart: React.FunctionComponent<QuickstartProps> = ({
</div>
</div>

<FrameworkIntegrations
integrationList={QUICKSTART_INTEGRATIONS}
apiKey={apiKey}
showColabLinks={showColabLinks}
/>
<FrameworkIntegrations stickyOffset={20} />
</div>
);
};
Expand Down
Copy link
Contributor

@aadereiko aadereiko Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a similar component ResizableSidePanel. This and existing ones are used for different purposes, so you can either:

  • align their designs - f.e. how dark the shadow is
  • re-use the one that we already have

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import { Sheet, SheetContent } from "@/components/ui/sheet";

type SideDialogProps = {
open: boolean;
setOpen: (open: boolean) => void;
children: React.ReactNode;
};

const SideDialog: React.FunctionComponent<SideDialogProps> = ({
open,
setOpen,
children,
}) => {
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetContent className="w-[calc(100vw-60px)] sm:max-w-full xl:w-[calc(100vw-240px)]">
{children}
</SheetContent>
</Sheet>
);
};

export default SideDialog;
Loading
Loading