Update skyvern UI responsiveness (#1098)

Co-authored-by: Muhammed Salih Altun <muhammedsalihaltun@gmail.com>
This commit is contained in:
Shuchang Zheng
2024-10-31 08:49:15 -07:00
committed by GitHub
parent de8e887e0f
commit 478b27ac52
13 changed files with 741 additions and 96 deletions

View File

@@ -0,0 +1,115 @@
import * as React from "react";
import { Drawer as DrawerPrimitive } from "vaul";
import { cn } from "@/util/utils";
const Drawer = ({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
);
Drawer.displayName = "Drawer";
const DrawerTrigger = DrawerPrimitive.Trigger;
const DrawerPortal = DrawerPrimitive.Portal;
const DrawerClose = DrawerPrimitive.Close;
const DrawerOverlay = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props}
/>
));
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className,
)}
{...props}
>
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
));
DrawerContent.displayName = "DrawerContent";
const DrawerHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
{...props}
/>
);
DrawerHeader.displayName = "DrawerHeader";
const DrawerFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
);
DrawerFooter.displayName = "DrawerFooter";
const DrawerTitle = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className,
)}
{...props}
/>
));
DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
const DrawerDescription = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
};

View File

@@ -1,6 +1,7 @@
import { DiscordLogoIcon } from "@radix-ui/react-icons";
import GitHubButton from "react-github-btn";
import { Link, useMatch } from "react-router-dom";
import { NavigationHamburgerMenu } from "./NavigationHamburgerMenu";
function Header() {
const match = useMatch("/workflows/:workflowPermanentId/edit");
@@ -11,24 +12,27 @@ function Header() {
return (
<header>
<div className="flex h-24 items-center justify-end gap-4 px-6">
<Link
to="https://discord.com/invite/fG2XXEuQX3"
target="_blank"
rel="noopener noreferrer"
>
<DiscordLogoIcon className="h-7 w-7" />
</Link>
<div className="h-7">
<GitHubButton
href="https://github.com/skyvern-ai/skyvern"
data-color-scheme="no-preference: dark; light: dark; dark: dark;"
data-size="large"
data-show-count="true"
aria-label="Star skyvern-ai/skyvern on GitHub"
<div className="flex h-24 items-center px-6">
<NavigationHamburgerMenu />
<div className="ml-auto flex gap-4">
<Link
to="https://discord.com/invite/fG2XXEuQX3"
target="_blank"
rel="noopener noreferrer"
>
Star
</GitHubButton>
<DiscordLogoIcon className="h-7 w-7" />
</Link>
<div className="h-7">
<GitHubButton
href="https://github.com/skyvern-ai/skyvern"
data-color-scheme="no-preference: dark; light: dark; dark: dark;"
data-size="large"
data-show-count="true"
aria-label="Star skyvern-ai/skyvern on GitHub"
>
Star
</GitHubButton>
</div>
</div>
</div>
</header>

View File

@@ -0,0 +1,34 @@
import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
import { HamburgerMenuIcon } from "@radix-ui/react-icons";
import { SidebarContent } from "./SidebarContent";
import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
function NavigationHamburgerMenu() {
return (
<div className="block lg:hidden">
<Drawer direction="left">
<DrawerTrigger asChild>
<HamburgerMenuIcon className="size-6 cursor-pointer" />
</DrawerTrigger>
<DrawerContent className="bottom-2 left-2 top-2 mt-0 w-64 rounded border-0 px-6">
<VisuallyHidden.Root>
<DrawerHeader>
<DrawerTitle>Skyvern</DrawerTitle>
<DrawerDescription>Skyvern App Navigation</DrawerDescription>
</DrawerHeader>
</VisuallyHidden.Root>
<SidebarContent />
</DrawerContent>
</Drawer>
</div>
);
}
export { NavigationHamburgerMenu };

View File

@@ -1,59 +1,21 @@
import { Link, Outlet } from "react-router-dom";
import { Toaster } from "@/components/ui/toaster";
import { SideNav } from "./SideNav";
import { PinLeftIcon, PinRightIcon } from "@radix-ui/react-icons";
import { Logo } from "@/components/Logo";
import { cn } from "@/util/utils";
import { Button } from "@/components/ui/button";
import { LogoMinimized } from "@/components/LogoMinimized";
import { Header } from "./Header";
import { useSidebarStore } from "@/store/SidebarStore";
import { cn } from "@/util/utils";
import { Outlet } from "react-router-dom";
import { Header } from "./Header";
import { Sidebar } from "./Sidebar";
function RootLayout() {
const { collapsed, setCollapsed } = useSidebarStore();
const collapsed = useSidebarStore((state) => state.collapsed);
return (
<>
<div className="h-full w-full">
<aside
className={cn("fixed h-screen min-h-screen border-r-2 px-6", {
"w-64": !collapsed,
"w-28": collapsed,
})}
>
<div className="flex h-full flex-col">
<Link to={window.location.origin}>
<div className="flex h-24 items-center">
{collapsed ? <LogoMinimized /> : <Logo />}
</div>
</Link>
<SideNav collapsed={collapsed} />
<div
className={cn("mt-auto flex min-h-16", {
"justify-center": collapsed,
"justify-end": !collapsed,
})}
>
<Button
size="icon"
variant="ghost"
onClick={() => {
setCollapsed(!collapsed);
}}
>
{collapsed ? (
<PinRightIcon className="h-6 w-6" />
) : (
<PinLeftIcon className="h-6 w-6" />
)}
</Button>
</div>
</div>
</aside>
<Sidebar />
<Header />
<main
className={cn("pb-4 pl-64", {
"pl-28": collapsed,
className={cn("lg:pb-4 lg:pl-64", {
"lg:pl-28": collapsed,
})}
>
<Outlet />

View File

@@ -0,0 +1,23 @@
import { useSidebarStore } from "@/store/SidebarStore";
import { cn } from "@/util/utils";
import { SidebarContent } from "./SidebarContent";
function Sidebar() {
const collapsed = useSidebarStore((state) => state.collapsed);
return (
<aside
className={cn(
"fixed hidden h-screen min-h-screen border-r-2 px-6 lg:block",
{
"w-64": !collapsed,
"w-28": collapsed,
},
)}
>
<SidebarContent useCollapsedState />
</aside>
);
}
export { Sidebar };

View File

@@ -0,0 +1,50 @@
import { Logo } from "@/components/Logo";
import { LogoMinimized } from "@/components/LogoMinimized";
import { useSidebarStore } from "@/store/SidebarStore";
import { Link } from "react-router-dom";
import { SideNav } from "./SideNav";
import { cn } from "@/util/utils";
import { Button } from "@/components/ui/button";
import { PinLeftIcon, PinRightIcon } from "@radix-ui/react-icons";
type Props = {
useCollapsedState?: boolean;
};
function SidebarContent({ useCollapsedState }: Props) {
const { collapsed: collapsedState, setCollapsed } = useSidebarStore();
const collapsed = useCollapsedState ? collapsedState : false;
return (
<div className="flex h-full flex-col">
<Link to={window.location.origin}>
<div className="flex h-24 items-center">
{collapsed ? <LogoMinimized /> : <Logo />}
</div>
</Link>
<SideNav collapsed={collapsed} />
<div
className={cn("mt-auto flex min-h-16", {
"justify-center": collapsed,
"justify-end": !collapsed,
})}
>
<Button
size="icon"
variant="ghost"
onClick={() => {
setCollapsed(!collapsed);
}}
>
{collapsed ? (
<PinRightIcon className="h-6 w-6" />
) : (
<PinLeftIcon className="hidden h-6 w-6 lg:block" />
)}
</Button>
</div>
</div>
);
}
export { SidebarContent };

View File

@@ -2,7 +2,7 @@ import { Outlet } from "react-router-dom";
function SettingsPageLayout() {
return (
<div className="container mx-auto px-8">
<div className="container mx-auto">
<main>
<Outlet />
</main>

View File

@@ -2,7 +2,7 @@ import { Outlet } from "react-router-dom";
function TasksPageLayout() {
return (
<div className="container mx-auto px-8">
<div className="container mx-auto">
<main>
<Outlet />
</main>

View File

@@ -2,7 +2,7 @@ import { Outlet } from "react-router-dom";
function CreateNewTaskLayout() {
return (
<main className="container mx-auto px-8">
<main className="container mx-auto">
<Outlet />
</main>
);

View File

@@ -149,7 +149,7 @@ function PromptBox() {
<span className="text-2xl">
What task would you like to accomplish?
</span>
<div className="flex w-[35rem] max-w-xl items-center rounded-xl bg-slate-700 py-2 pr-4">
<div className="flex w-1/2 max-w-xl items-center rounded-xl bg-slate-700 py-2 pr-4">
<Textarea
className="min-h-0 resize-none rounded-xl border-transparent px-4 hover:border-transparent focus-visible:ring-0"
value={prompt}

View File

@@ -7,7 +7,7 @@ function WorkflowsPageLayout() {
return (
<main
className={cn({
"container mx-auto px-8": !match,
"container mx-auto": !match,
})}
>
<Outlet />