fix: sidebar animations, colors and minor design fixes (#4379)
This commit is contained in:
parent
7b5ba8e8f5
commit
91b650fd03
21 changed files with 323 additions and 352 deletions
|
|
@ -79,7 +79,7 @@ export default function FlowToolbar(): JSX.Element {
|
|||
<button
|
||||
disabled={!hasApiKey || !validApiKey || !hasStore}
|
||||
className={classNames(
|
||||
"share-button",
|
||||
"relative inline-flex h-8 w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-accent",
|
||||
!hasApiKey || !validApiKey || !hasStore
|
||||
? "text-muted-foreground"
|
||||
: "",
|
||||
|
|
@ -93,13 +93,13 @@ export default function FlowToolbar(): JSX.Element {
|
|||
<ForwardedIconComponent
|
||||
name="Share2"
|
||||
className={classNames(
|
||||
"-m-0.5 -ml-1 h-4 w-4",
|
||||
"h-4 w-4",
|
||||
!hasApiKey || !validApiKey || !hasStore
|
||||
? "extra-side-bar-save-disable"
|
||||
: "",
|
||||
)}
|
||||
/>
|
||||
Share
|
||||
<span className="hidden md:block">Share</span>
|
||||
</>
|
||||
</button>
|
||||
</ShadTooltip>
|
||||
|
|
@ -134,26 +134,26 @@ export default function FlowToolbar(): JSX.Element {
|
|||
>
|
||||
<div
|
||||
data-testid="playground-btn-flow-io"
|
||||
className="relative inline-flex w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-accent"
|
||||
className="relative inline-flex h-8 w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-accent"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="Play"
|
||||
className={"h-4 w-4 transition-all"}
|
||||
/>
|
||||
Playground
|
||||
<span className="hidden md:block">Playground</span>
|
||||
</div>
|
||||
</IOModal>
|
||||
) : (
|
||||
<ShadTooltip content="Add a Chat Input or Chat Output to use the playground">
|
||||
<div
|
||||
className={`relative inline-flex w-full cursor-not-allowed items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-muted-foreground transition-all duration-150 ease-in-out`}
|
||||
className={`relative inline-flex h-8 w-full cursor-not-allowed items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-muted-foreground transition-all duration-150 ease-in-out`}
|
||||
data-testid="playground-btn-flow"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="BotMessageSquareIcon"
|
||||
className={"h-5 w-5 transition-all"}
|
||||
/>
|
||||
Playground
|
||||
<span className="hidden md:block">Playground</span>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
)}
|
||||
|
|
@ -169,14 +169,14 @@ export default function FlowToolbar(): JSX.Element {
|
|||
>
|
||||
<div
|
||||
className={classNames(
|
||||
"relative inline-flex w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-accent",
|
||||
"relative inline-flex h-8 w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-accent",
|
||||
)}
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="Code2"
|
||||
className={"h-4 w-4"}
|
||||
/>
|
||||
API
|
||||
<span className="hidden md:block">API</span>
|
||||
</div>
|
||||
</ApiModal>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { IS_MAC } from "@/constants/constants";
|
||||
import { addPlusSignes, cn, sortShortcuts } from "@/utils/utils";
|
||||
import RenderKey from "./components/renderKey";
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ const badgeVariants = cva(
|
|||
destructive:
|
||||
"bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground",
|
||||
outline: "text-primary/80 border-ring/60",
|
||||
secondaryStatic: "bg-input text-muted-foreground",
|
||||
pinkStatic: "bg-accent-pink text-accent-pink-foreground",
|
||||
secondaryStatic: "bg-input text-muted-foreground border-0",
|
||||
pinkStatic: "bg-accent-pink text-accent-pink-foreground border-0",
|
||||
},
|
||||
size: {
|
||||
sm: "h-4 text-xs",
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@ import { VariantProps, cva } from "class-variance-authority";
|
|||
import { PanelLeft } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { useIsMobile } from "../../hooks/use-mobile";
|
||||
import { cn } from "../../utils/utils";
|
||||
import { Button } from "./button";
|
||||
import { Input } from "./input";
|
||||
import { Separator } from "./separator";
|
||||
import { Sheet, SheetContent } from "./sheet";
|
||||
import { Skeleton } from "./skeleton";
|
||||
import {
|
||||
Tooltip,
|
||||
|
|
@ -22,17 +20,13 @@ import {
|
|||
const SIDEBAR_COOKIE_NAME = "sidebar:state";
|
||||
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
||||
const SIDEBAR_WIDTH = "19rem";
|
||||
const SIDEBAR_WIDTH_MOBILE = "18rem";
|
||||
const SIDEBAR_WIDTH_ICON = "3rem";
|
||||
const SIDEBAR_WIDTH_ICON = "4rem";
|
||||
const SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
||||
|
||||
type SidebarContext = {
|
||||
state: "expanded" | "collapsed";
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
openMobile: boolean;
|
||||
setOpenMobile: (open: boolean) => void;
|
||||
isMobile: boolean;
|
||||
toggleSidebar: () => void;
|
||||
};
|
||||
|
||||
|
|
@ -53,6 +47,7 @@ const SidebarProvider = React.forwardRef<
|
|||
defaultOpen?: boolean;
|
||||
open?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
width?: string;
|
||||
}
|
||||
>(
|
||||
(
|
||||
|
|
@ -63,13 +58,11 @@ const SidebarProvider = React.forwardRef<
|
|||
className,
|
||||
style,
|
||||
children,
|
||||
width = SIDEBAR_WIDTH,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const isMobile = useIsMobile();
|
||||
const [openMobile, setOpenMobile] = React.useState(false);
|
||||
|
||||
// This is the internal state of the sidebar.
|
||||
// We use openProp and setOpenProp for control from outside the component.
|
||||
const [_open, _setOpen] = React.useState(defaultOpen);
|
||||
|
|
@ -92,10 +85,8 @@ const SidebarProvider = React.forwardRef<
|
|||
|
||||
// Helper to toggle the sidebar.
|
||||
const toggleSidebar = React.useCallback(() => {
|
||||
return isMobile
|
||||
? setOpenMobile((open) => !open)
|
||||
: setOpen((open) => !open);
|
||||
}, [isMobile, setOpen, setOpenMobile]);
|
||||
return setOpen((open) => !open);
|
||||
}, [setOpen]);
|
||||
|
||||
// Adds a keyboard shortcut to toggle the sidebar.
|
||||
React.useEffect(() => {
|
||||
|
|
@ -122,20 +113,9 @@ const SidebarProvider = React.forwardRef<
|
|||
state,
|
||||
open,
|
||||
setOpen,
|
||||
isMobile,
|
||||
openMobile,
|
||||
setOpenMobile,
|
||||
toggleSidebar,
|
||||
}),
|
||||
[
|
||||
state,
|
||||
open,
|
||||
setOpen,
|
||||
isMobile,
|
||||
openMobile,
|
||||
setOpenMobile,
|
||||
toggleSidebar,
|
||||
],
|
||||
[state, open, setOpen, toggleSidebar],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
@ -144,7 +124,7 @@ const SidebarProvider = React.forwardRef<
|
|||
<div
|
||||
style={
|
||||
{
|
||||
"--sidebar-width": SIDEBAR_WIDTH,
|
||||
"--sidebar-width": width,
|
||||
"--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
|
||||
...style,
|
||||
} as React.CSSProperties
|
||||
|
|
@ -184,47 +164,33 @@ const Sidebar = React.forwardRef<
|
|||
},
|
||||
ref,
|
||||
) => {
|
||||
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
||||
const { state } = useSidebar();
|
||||
|
||||
if (collapsible === "none") {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-full w-[--sidebar-width] flex-col bg-background text-foreground",
|
||||
"group flex h-full w-[--sidebar-width] flex-col bg-background text-foreground",
|
||||
className,
|
||||
)}
|
||||
data-side={side}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
|
||||
<SheetContent
|
||||
<div
|
||||
data-sidebar="sidebar"
|
||||
data-mobile="true"
|
||||
className="w-[--sidebar-width] bg-background p-0 text-foreground [&>button]:hidden"
|
||||
style={
|
||||
{
|
||||
"--sidebar-width": SIDEBAR_WIDTH_MOBILE,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
side={side}
|
||||
className="flex h-full w-full flex-col group-data-[side=left]:border-r group-data-[side=right]:border-l"
|
||||
>
|
||||
<div className="flex h-full w-full flex-col">{children}</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="group peer relative flex h-full flex-col md:block"
|
||||
className="group peer relative block h-full flex-col"
|
||||
data-state={state}
|
||||
data-collapsible={state === "collapsed" ? collapsible : ""}
|
||||
data-variant={variant}
|
||||
|
|
@ -239,11 +205,18 @@ const Sidebar = React.forwardRef<
|
|||
variant === "floating" || variant === "inset"
|
||||
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
|
||||
: "group-data-[collapsible=icon]:w-[--sidebar-width-icon]",
|
||||
// Keep icon width on mobile when collapsed
|
||||
collapsible === "icon"
|
||||
? "max-sm:w-[--sidebar-width-icon]"
|
||||
: "max-sm:w-0",
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
"absolute inset-y-0 z-10 hidden h-full w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex",
|
||||
"absolute inset-y-0 z-50 flex h-full transition-[left,right,width] duration-200 ease-linear",
|
||||
// Adjust width based on state and device
|
||||
"w-[--sidebar-width]",
|
||||
"max-sm:group-data-[state=collapsed]:w-[--sidebar-width-icon]",
|
||||
side === "left"
|
||||
? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
|
||||
: "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
|
||||
|
|
@ -251,13 +224,20 @@ const Sidebar = React.forwardRef<
|
|||
variant === "floating" || variant === "inset"
|
||||
? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]"
|
||||
: "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
||||
// Position absolute relative to parent container on mobile
|
||||
"max-sm:absolute max-sm:h-[100%] max-sm:group-data-[state=expanded]:bg-background/80",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
data-sidebar="sidebar"
|
||||
className="flex h-full w-full flex-col bg-background group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-border group-data-[variant=floating]:shadow"
|
||||
className={cn(
|
||||
"flex h-full w-full flex-col bg-background",
|
||||
"group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-border group-data-[variant=floating]:shadow",
|
||||
// Add shadow on mobile
|
||||
"max-sm:shadow-lg",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
@ -280,15 +260,21 @@ const SidebarTrigger = React.forwardRef<
|
|||
data-sidebar="trigger"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={cn("h-7 w-7", className)}
|
||||
className={cn("h-8 w-8", className)}
|
||||
onClick={(event) => {
|
||||
onClick?.(event);
|
||||
toggleSidebar();
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<PanelLeft />
|
||||
<span className="sr-only">Toggle Sidebar</span>
|
||||
{props.children ? (
|
||||
props.children
|
||||
) : (
|
||||
<>
|
||||
<PanelLeft />
|
||||
<span className="sr-only">Toggle Sidebar</span>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
|
|
@ -332,7 +318,7 @@ const SidebarInset = React.forwardRef<
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex min-h-svh flex-1 flex-col bg-background",
|
||||
"peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
|
||||
"peer-data-[variant=inset]:m-2 peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 peer-data-[variant=inset]:ml-0 peer-data-[variant=inset]:rounded-xl peer-data-[variant=inset]:shadow",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -350,7 +336,7 @@ const SidebarInput = React.forwardRef<
|
|||
ref={ref}
|
||||
data-sidebar="input"
|
||||
className={cn(
|
||||
"h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
"h-8 w-full bg-background shadow-none focus-visible:ring-1 focus-visible:ring-ring",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -448,7 +434,7 @@ const SidebarGroupLabel = React.forwardRef<
|
|||
ref={ref}
|
||||
data-sidebar="group-label"
|
||||
className={cn(
|
||||
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-semibold text-foreground/70 outline-none ring-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-semibold text-foreground/70 outline-none ring-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-1 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
|
||||
className,
|
||||
)}
|
||||
|
|
@ -469,9 +455,9 @@ const SidebarGroupAction = React.forwardRef<
|
|||
ref={ref}
|
||||
data-sidebar="group-action"
|
||||
className={cn(
|
||||
"absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-accent hover:text-accent-foreground focus-visible:ring-1 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
// Increases the hit area of the button on mobile.
|
||||
"after:absolute after:-inset-2 after:md:hidden",
|
||||
"after:-inset-2 after:hidden",
|
||||
"group-data-[collapsible=icon]:hidden",
|
||||
className,
|
||||
)}
|
||||
|
|
@ -521,11 +507,12 @@ const SidebarMenuItem = React.forwardRef<
|
|||
SidebarMenuItem.displayName = "SidebarMenuItem";
|
||||
|
||||
const sidebarMenuButtonVariants = cva(
|
||||
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-ring transition-[width,height,padding] hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-accent data-[active=true]:font-medium data-[active=true]:text-accent-foreground data-[state=open]:hover:bg-accent data-[state=open]:hover:text-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-ring transition-[width,height,padding] hover:bg-accent hover:text-accent-foreground focus-visible:ring-1 active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-accent data-[active=true]:font-medium data-[active=true]:text-accent-foreground data-[state=open]:hover:bg-accent data-[state=open]:hover:text-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "hover:bg-accent hover:text-accent-foreground",
|
||||
default:
|
||||
"text-secondary-foreground hover:bg-accent hover:text-accent-foreground ",
|
||||
outline:
|
||||
"bg-background shadow-[0_0_0_1px_hsl(var(--border))] hover:bg-accent hover:text-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--accent))]",
|
||||
},
|
||||
|
|
@ -563,7 +550,7 @@ const SidebarMenuButton = React.forwardRef<
|
|||
ref,
|
||||
) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
const { isMobile, state } = useSidebar();
|
||||
const { state } = useSidebar();
|
||||
|
||||
const button = (
|
||||
<Comp
|
||||
|
|
@ -592,7 +579,7 @@ const SidebarMenuButton = React.forwardRef<
|
|||
<TooltipContent
|
||||
side="right"
|
||||
align="center"
|
||||
hidden={state !== "collapsed" || isMobile}
|
||||
hidden={state !== "collapsed"}
|
||||
{...tooltip}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
|
@ -615,9 +602,9 @@ const SidebarMenuAction = React.forwardRef<
|
|||
ref={ref}
|
||||
data-sidebar="menu-action"
|
||||
className={cn(
|
||||
"absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-foreground outline-none ring-ring transition-transform hover:bg-accent hover:text-accent-foreground focus-visible:ring-1 peer-hover/menu-button:text-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
// Increases the hit area of the button on mobile.
|
||||
"after:absolute after:-inset-2 after:md:hidden",
|
||||
"after:-inset-2 after:hidden",
|
||||
"peer-data-[size=sm]/menu-button:top-1",
|
||||
"peer-data-[size=default]/menu-button:top-1.5",
|
||||
"peer-data-[size=lg]/menu-button:top-2.5",
|
||||
|
|
@ -731,7 +718,7 @@ const SidebarMenuSubButton = React.forwardRef<
|
|||
data-size={size}
|
||||
data-active={isActive}
|
||||
className={cn(
|
||||
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-foreground outline-none ring-ring hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-accent-foreground",
|
||||
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-foreground outline-none ring-ring hover:bg-accent hover:text-accent-foreground focus-visible:ring-1 active:bg-accent active:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-accent-foreground",
|
||||
"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground",
|
||||
size === "sm" && "text-xs",
|
||||
size === "md" && "text-sm",
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ const SvgAWS = (props) => (
|
|||
<style>{".st1{fill-rule:evenodd;clip-rule:evenodd;fill:#f90}"}</style>
|
||||
<path
|
||||
d="M86.4 66.4c0 3.7.4 6.7 1.1 8.9.8 2.2 1.8 4.6 3.2 7.2.5.8.7 1.6.7 2.3 0 1-.6 2-1.9 3L83.2 92c-.9.6-1.8.9-2.6.9-1 0-2-.5-3-1.4-1.4-1.5-2.6-3.1-3.6-4.7-1-1.7-2-3.6-3.1-5.9-7.8 9.2-17.6 13.8-29.4 13.8-8.4 0-15.1-2.4-20-7.2-4.9-4.8-7.4-11.2-7.4-19.2 0-8.5 3-15.4 9.1-20.6 6.1-5.2 14.2-7.8 24.5-7.8 3.4 0 6.9.3 10.6.8 3.7.5 7.5 1.3 11.5 2.2v-7.3c0-7.6-1.6-12.9-4.7-16-3.2-3.1-8.6-4.6-16.3-4.6-3.5 0-7.1.4-10.8 1.3-3.7.9-7.3 2-10.8 3.4-1.6.7-2.8 1.1-3.5 1.3-.7.2-1.2.3-1.6.3-1.4 0-2.1-1-2.1-3.1v-4.9c0-1.6.2-2.8.7-3.5.5-.7 1.4-1.4 2.8-2.1 3.5-1.8 7.7-3.3 12.6-4.5C41 1.9 46.2 1.3 51.7 1.3c11.9 0 20.6 2.7 26.2 8.1 5.5 5.4 8.3 13.6 8.3 24.6v32.4zM45.8 81.6c3.3 0 6.7-.6 10.3-1.8 3.6-1.2 6.8-3.4 9.5-6.4 1.6-1.9 2.8-4 3.4-6.4.6-2.4 1-5.3 1-8.7v-4.2c-2.9-.7-6-1.3-9.2-1.7-3.2-.4-6.3-.6-9.4-.6-6.7 0-11.6 1.3-14.9 4-3.3 2.7-4.9 6.5-4.9 11.5 0 4.7 1.2 8.2 3.7 10.6 2.4 2.5 5.9 3.7 10.5 3.7zm80.3 10.8c-1.8 0-3-.3-3.8-1-.8-.6-1.5-2-2.1-3.9L96.7 10.2c-.6-2-.9-3.3-.9-4 0-1.6.8-2.5 2.4-2.5h9.8c1.9 0 3.2.3 3.9 1 .8.6 1.4 2 2 3.9l16.8 66.2 15.6-66.2c.5-2 1.1-3.3 1.9-3.9.8-.6 2.2-1 4-1h8c1.9 0 3.2.3 4 1 .8.6 1.5 2 1.9 3.9l15.8 67 17.3-67c.6-2 1.3-3.3 2-3.9.8-.6 2.1-1 3.9-1h9.3c1.6 0 2.5.8 2.5 2.5 0 .5-.1 1-.2 1.6-.1.6-.3 1.4-.7 2.5l-24.1 77.3c-.6 2-1.3 3.3-2.1 3.9-.8.6-2.1 1-3.8 1h-8.6c-1.9 0-3.2-.3-4-1-.8-.7-1.5-2-1.9-4L156 23l-15.4 64.4c-.5 2-1.1 3.3-1.9 4-.8.7-2.2 1-4 1h-8.6zm128.5 2.7c-5.2 0-10.4-.6-15.4-1.8-5-1.2-8.9-2.5-11.5-4-1.6-.9-2.7-1.9-3.1-2.8-.4-.9-.6-1.9-.6-2.8v-5.1c0-2.1.8-3.1 2.3-3.1.6 0 1.2.1 1.8.3.6.2 1.5.6 2.5 1 3.4 1.5 7.1 2.7 11 3.5 4 .8 7.9 1.2 11.9 1.2 6.3 0 11.2-1.1 14.6-3.3 3.4-2.2 5.2-5.4 5.2-9.5 0-2.8-.9-5.1-2.7-7-1.8-1.9-5.2-3.6-10.1-5.2L246 52c-7.3-2.3-12.7-5.7-16-10.2-3.3-4.4-5-9.3-5-14.5 0-4.2.9-7.9 2.7-11.1 1.8-3.2 4.2-6 7.2-8.2 3-2.3 6.4-4 10.4-5.2 4-1.2 8.2-1.7 12.6-1.7 2.2 0 4.5.1 6.7.4 2.3.3 4.4.7 6.5 1.1 2 .5 3.9 1 5.7 1.6 1.8.6 3.2 1.2 4.2 1.8 1.4.8 2.4 1.6 3 2.5.6.8.9 1.9.9 3.3v4.7c0 2.1-.8 3.2-2.3 3.2-.8 0-2.1-.4-3.8-1.2-5.7-2.6-12.1-3.9-19.2-3.9-5.7 0-10.2.9-13.3 2.8-3.1 1.9-4.7 4.8-4.7 8.9 0 2.8 1 5.2 3 7.1 2 1.9 5.7 3.8 11 5.5l14.2 4.5c7.2 2.3 12.4 5.5 15.5 9.6 3.1 4.1 4.6 8.8 4.6 14 0 4.3-.9 8.2-2.6 11.6-1.8 3.4-4.2 6.4-7.3 8.8-3.1 2.5-6.8 4.3-11.1 5.6-4.5 1.4-9.2 2.1-14.3 2.1z"
|
||||
style={{
|
||||
fill: "#252f3e",
|
||||
}}
|
||||
fill={props.isdark ? "#ffffff" : "#252f3e"}
|
||||
/>
|
||||
<path
|
||||
d="M273.5 143.7c-32.9 24.3-80.7 37.2-121.8 37.2-57.6 0-109.5-21.3-148.7-56.7-3.1-2.8-.3-6.6 3.4-4.4 42.4 24.6 94.7 39.5 148.8 39.5 36.5 0 76.6-7.6 113.5-23.2 5.5-2.5 10.2 3.6 4.8 7.6z"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { useDarkStore } from "@/stores/darkStore";
|
||||
import React, { forwardRef } from "react";
|
||||
import SvgAWS from "./AWS";
|
||||
|
||||
export const AWSIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <SvgAWS ref={ref} {...props} />;
|
||||
const isdark = useDarkStore((state) => state.dark);
|
||||
return <SvgAWS ref={ref} isdark={isdark} {...props} />;
|
||||
},
|
||||
);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -27,17 +27,9 @@ export const GradientSave = forwardRef<
|
|||
>((props, ref) => {
|
||||
return (
|
||||
<>
|
||||
<svg width="0" height="0" style={{ position: "absolute" }}>
|
||||
<defs>
|
||||
<linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop className="gradient-start" offset="0%" />
|
||||
<stop className="gradient-end" offset="100%" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<ForwardedIconComponent
|
||||
name="Save"
|
||||
stroke="url(#grad2)"
|
||||
stroke="url(#x-gradient)"
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export const SvgRedis = (props) => (
|
|||
height="35"
|
||||
version="1"
|
||||
viewBox="0 0 750 750"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<filter id="959fca5e72" width="100%" height="100%" x="0%" y="0%">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import CanvasControls, {
|
|||
CustomControlButton,
|
||||
} from "@/components/canvasControlsComponent";
|
||||
import FlowToolbar from "@/components/flowToolbarComponent";
|
||||
import ForwardedIconComponent from "@/components/genericIconComponent";
|
||||
import LoadingComponent from "@/components/loadingComponent";
|
||||
import { SidebarTrigger, useSidebar } from "@/components/ui/sidebar";
|
||||
import {
|
||||
NOTE_NODE_MIN_HEIGHT,
|
||||
NOTE_NODE_MIN_WIDTH,
|
||||
|
|
@ -16,7 +18,7 @@ import useAutoSaveFlow from "@/hooks/flows/use-autosave-flow";
|
|||
import useUploadFlow from "@/hooks/flows/use-upload-flow";
|
||||
import { useAddComponent } from "@/hooks/useAddComponent";
|
||||
import { nodeColorsName } from "@/utils/styleUtils";
|
||||
import { isSupportedNodeTypes } from "@/utils/utils";
|
||||
import { cn, isSupportedNodeTypes } from "@/utils/utils";
|
||||
import _, { cloneDeep } from "lodash";
|
||||
import {
|
||||
KeyboardEvent,
|
||||
|
|
@ -33,6 +35,7 @@ import ReactFlow, {
|
|||
Edge,
|
||||
NodeDragHandler,
|
||||
OnSelectionChangeParams,
|
||||
Panel,
|
||||
SelectionDragHandler,
|
||||
updateEdge,
|
||||
useReactFlow,
|
||||
|
|
@ -583,6 +586,8 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
|
|||
document.documentElement.style.setProperty("--selected", innerColor);
|
||||
};
|
||||
|
||||
const { open } = useSidebar();
|
||||
|
||||
return (
|
||||
<div className="h-full w-full bg-canvas" ref={reactFlowWrapper}>
|
||||
{showCanvas ? (
|
||||
|
|
@ -640,6 +645,23 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
|
|||
<FlowToolbar />
|
||||
</>
|
||||
)}
|
||||
<Panel
|
||||
className={cn(
|
||||
"react-flow__controls !m-2 flex gap-1.5 rounded-md border border-secondary-hover bg-background fill-foreground stroke-foreground p-1.5 text-primary shadow transition-all duration-300 [&>button]:border-0 [&>button]:bg-background hover:[&>button]:bg-accent",
|
||||
open
|
||||
? "pointer-events-none -translate-x-full opacity-0"
|
||||
: "pointer-events-auto opacity-100",
|
||||
)}
|
||||
position="top-left"
|
||||
>
|
||||
<SidebarTrigger className="h-fit w-fit px-3 py-1.5">
|
||||
<ForwardedIconComponent
|
||||
name="PanelRightClose"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
Components
|
||||
</SidebarTrigger>
|
||||
</Panel>
|
||||
<SelectionMenu
|
||||
lastSelection={lastSelection}
|
||||
isVisible={selectionMenuVisible}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ export function SidebarFilterComponent({
|
|||
resetFilters: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="mb-0.5 flex w-full items-center justify-between rounded border bg-accent-indigo p-2 text-sm text-accent-indigo-foreground">
|
||||
<div className="mb-0.5 flex w-full items-center justify-between rounded border bg-accent-indigo p-2 text-sm text-foreground">
|
||||
<div className="flex flex-1 items-center gap-1.5">
|
||||
<ForwardedIconComponent
|
||||
name="ListFilter"
|
||||
className="h-4 w-4 shrink-0 stroke-2"
|
||||
className="h-4 w-4 shrink-0 stroke-2 text-accent-indigo-foreground"
|
||||
/>
|
||||
<div className="flex flex-1">
|
||||
{isInput ? "Input" : "Output"}:{" "}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { DragEventHandler, forwardRef, useRef, useState } from "react";
|
|||
import IconComponent, {
|
||||
ForwardedIconComponent,
|
||||
} from "../../../../../../components/genericIconComponent";
|
||||
import ShadTooltip from "../../../../../../components/shadTooltipComponent";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
|
@ -118,7 +119,7 @@ export const SidebarDraggableComponent = forwardRef(
|
|||
data-testid={sectionName + display_name}
|
||||
id={sectionName + display_name}
|
||||
className={cn(
|
||||
"group/draggable flex cursor-grab items-center gap-2 rounded-md bg-muted p-3 hover:bg-accent",
|
||||
"group/draggable flex cursor-grab items-center gap-2 rounded-md bg-muted p-3 hover:bg-secondary-hover/75",
|
||||
error ? "cursor-not-allowed select-none" : "",
|
||||
)}
|
||||
draggable={!error}
|
||||
|
|
@ -134,9 +135,11 @@ export const SidebarDraggableComponent = forwardRef(
|
|||
>
|
||||
<ForwardedIconComponent name={icon} className="h-5 w-5 shrink-0" />
|
||||
<div className="flex flex-1 items-center overflow-hidden">
|
||||
<span className="truncate text-sm font-semibold">
|
||||
{display_name}
|
||||
</span>
|
||||
<ShadTooltip content={display_name} styleClasses="z-50">
|
||||
<span className="truncate text-sm font-semibold">
|
||||
{display_name}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
{beta && (
|
||||
<Badge
|
||||
variant="pinkStatic"
|
||||
|
|
@ -161,18 +164,18 @@ export const SidebarDraggableComponent = forwardRef(
|
|||
variant="ghost"
|
||||
size="icon"
|
||||
tabIndex={-1}
|
||||
className="text-muted-foreground hover:text-primary group-focus/draggable:text-primary"
|
||||
className="text-primary"
|
||||
onClick={() => addComponent(apiClass, itemName)}
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="Plus"
|
||||
className="h-4 w-4 shrink-0 opacity-0 transition-all group-hover/draggable:opacity-100 group-focus/draggable:opacity-100"
|
||||
className="h-4 w-4 shrink-0 transition-all group-hover/draggable:opacity-100 group-focus/draggable:opacity-100 sm:opacity-0"
|
||||
/>
|
||||
</Button>
|
||||
<div ref={popoverRef}>
|
||||
<ForwardedIconComponent
|
||||
name="GripVertical"
|
||||
className="h-4 w-4 shrink-0 text-muted-foreground"
|
||||
className="h-4 w-4 shrink-0 text-muted-foreground group-hover/draggable:text-primary"
|
||||
/>
|
||||
<SelectTrigger tabIndex={-1}></SelectTrigger>
|
||||
<SelectContent
|
||||
|
|
|
|||
|
|
@ -6,11 +6,6 @@ import ForwardedIconComponent from "@/components/genericIconComponent";
|
|||
import ShadTooltip from "@/components/shadTooltipComponent";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import {
|
||||
Disclosure,
|
||||
DisclosureContent,
|
||||
|
|
@ -29,6 +24,7 @@ import {
|
|||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSkeleton,
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { CustomLink } from "@/customization/components/custom-link";
|
||||
|
|
@ -302,23 +298,41 @@ export function FlowSidebarComponent() {
|
|||
}
|
||||
};
|
||||
|
||||
const hasBundleItems = bundles.some(
|
||||
(item) =>
|
||||
dataFilter[item.name] && Object.keys(dataFilter[item.name]).length > 0,
|
||||
);
|
||||
|
||||
function handleClearSearch() {
|
||||
setSearch("");
|
||||
setFilterData(data);
|
||||
setOpenCategories([]);
|
||||
}
|
||||
|
||||
return (
|
||||
<Sidebar data-testid="shad-sidebar">
|
||||
<Sidebar collapsible="offcanvas" data-testid="shad-sidebar">
|
||||
<SidebarHeader className="flex w-full flex-col gap-4 p-4 pb-1">
|
||||
<Disclosure open={showConfig} onOpenChange={setShowConfig}>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<h3 className="text-sm font-semibold">Components</h3>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<SidebarTrigger className="text-muted-foreground">
|
||||
<ForwardedIconComponent name="PanelLeftClose" />
|
||||
</SidebarTrigger>
|
||||
<h3 className="flex-1 text-sm font-semibold">Components</h3>
|
||||
<DisclosureTrigger>
|
||||
<Button
|
||||
variant={showConfig ? "ghostActive" : "ghost"}
|
||||
size="iconMd"
|
||||
data-testid="sidebar-options-trigger"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="SlidersHorizontal"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
</Button>
|
||||
<div>
|
||||
<ShadTooltip content="Component settings" styleClasses="z-50">
|
||||
<Button
|
||||
variant={showConfig ? "ghostActive" : "ghost"}
|
||||
size="iconMd"
|
||||
data-testid="sidebar-options-trigger"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="SlidersHorizontal"
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
</Button>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
</DisclosureTrigger>
|
||||
</div>
|
||||
<DisclosureContent>
|
||||
|
|
@ -368,6 +382,7 @@ export function FlowSidebarComponent() {
|
|||
type="search"
|
||||
data-testid="sidebar-search-input"
|
||||
className="w-full rounded-lg bg-background pl-8 text-sm"
|
||||
placeholder=""
|
||||
onFocus={() => setIsInputFocused(true)}
|
||||
onBlur={() => setIsInputFocused(false)}
|
||||
value={search}
|
||||
|
|
@ -410,9 +425,8 @@ export function FlowSidebarComponent() {
|
|||
(item) =>
|
||||
dataFilter[item.name] &&
|
||||
Object.keys(dataFilter[item.name]).length > 0 && (
|
||||
<Collapsible
|
||||
<Disclosure
|
||||
key={item.name}
|
||||
className="group/collapsible"
|
||||
open={openCategories.includes(item.name)}
|
||||
onOpenChange={(isOpen) => {
|
||||
setOpenCategories((prev) =>
|
||||
|
|
@ -423,7 +437,7 @@ export function FlowSidebarComponent() {
|
|||
}}
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger asChild>
|
||||
<DisclosureTrigger className="group/collapsible">
|
||||
<SidebarMenuButton asChild>
|
||||
<div
|
||||
data-testid={`disclosure-${item.display_name.toLocaleLowerCase()}`}
|
||||
|
|
@ -435,19 +449,19 @@ export function FlowSidebarComponent() {
|
|||
>
|
||||
<ForwardedIconComponent
|
||||
name={item.icon}
|
||||
className="h-4 w-4 text-muted-foreground group-data-[state=open]/collapsible:text-pink-600 group-data-[state=open]/collapsible:dark:text-pink-400"
|
||||
className="group-aria-expanded/collapsible:x-gradient h-4 w-4"
|
||||
/>
|
||||
<span className="group-data-[state=open]/collapsible:font-semibold">
|
||||
<span className="group-aria-expanded/collapsible:font-semibold">
|
||||
{item.display_name}
|
||||
</span>
|
||||
<ForwardedIconComponent
|
||||
name="ChevronRight"
|
||||
className="h-4 w-4 text-muted-foreground transition-all group-data-[state=open]/collapsible:rotate-90"
|
||||
className="h-4 w-4 text-muted-foreground transition-all group-aria-expanded/collapsible:rotate-90"
|
||||
/>
|
||||
</div>
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
</DisclosureTrigger>
|
||||
<DisclosureContent>
|
||||
<div className="flex flex-col gap-1 py-2">
|
||||
{Object.keys(dataFilter[item.name])
|
||||
.sort((a, b) =>
|
||||
|
|
@ -516,152 +530,147 @@ export function FlowSidebarComponent() {
|
|||
</ShadTooltip>
|
||||
))}
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</DisclosureContent>
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
</Disclosure>
|
||||
),
|
||||
)}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Bundles</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{!data
|
||||
? Array.from({ length: 5 }).map((_, index) => (
|
||||
<SidebarMenuItem key={index}>
|
||||
<SidebarMenuSkeleton />
|
||||
</SidebarMenuItem>
|
||||
))
|
||||
: bundles.map(
|
||||
(item) =>
|
||||
dataFilter[item.name] &&
|
||||
Object.keys(dataFilter[item.name]).length > 0 && (
|
||||
<Collapsible
|
||||
key={item.name}
|
||||
className="group/collapsible"
|
||||
open={openCategories.includes(item.name)}
|
||||
onOpenChange={(isOpen) => {
|
||||
setOpenCategories((prev) =>
|
||||
isOpen
|
||||
? [...prev, item.name]
|
||||
: prev.filter((cat) => cat !== item.name),
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton asChild>
|
||||
<div
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) =>
|
||||
handleKeyDown(e, item.name)
|
||||
}
|
||||
className="flex cursor-pointer items-center gap-2"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name={item.icon}
|
||||
className="h-4 w-4 text-muted-foreground group-data-[state=open]/collapsible:text-pink-600 group-data-[state=open]/collapsible:dark:text-pink-400"
|
||||
/>
|
||||
<span className="group-data-[state=open]/collapsible:font-semibold">
|
||||
{item.display_name}
|
||||
</span>
|
||||
<ForwardedIconComponent
|
||||
name="ChevronRight"
|
||||
className="h-4 w-4 text-muted-foreground transition-all group-data-[state=open]/collapsible:rotate-90"
|
||||
/>
|
||||
</div>
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<div className="flex flex-col gap-1 py-2">
|
||||
{Object.keys(dataFilter[item.name])
|
||||
.sort((a, b) =>
|
||||
sensitiveSort(
|
||||
dataFilter[item.name][a].display_name,
|
||||
dataFilter[item.name][b].display_name,
|
||||
),
|
||||
)
|
||||
.map((SBItemName: string, idx) => (
|
||||
<ShadTooltip
|
||||
content={
|
||||
{hasBundleItems && (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Bundles</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{bundles.map(
|
||||
(item) =>
|
||||
dataFilter[item.name] &&
|
||||
Object.keys(dataFilter[item.name]).length > 0 && (
|
||||
<Disclosure
|
||||
key={item.name}
|
||||
open={openCategories.includes(item.name)}
|
||||
onOpenChange={(isOpen) => {
|
||||
setOpenCategories((prev) =>
|
||||
isOpen
|
||||
? [...prev, item.name]
|
||||
: prev.filter((cat) => cat !== item.name),
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<DisclosureTrigger className="group/collapsible">
|
||||
<SidebarMenuButton asChild>
|
||||
<div
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) =>
|
||||
handleKeyDown(e, item.name)
|
||||
}
|
||||
className="flex cursor-pointer items-center gap-2"
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name={item.icon}
|
||||
className="h-4 w-4 text-muted-foreground group-aria-expanded/collapsible:text-primary"
|
||||
/>
|
||||
<span className="group-aria-expanded/collapsible:font-semibold">
|
||||
{item.display_name}
|
||||
</span>
|
||||
<ForwardedIconComponent
|
||||
name="ChevronRight"
|
||||
className="h-4 w-4 text-muted-foreground transition-all group-aria-expanded/collapsible:rotate-90"
|
||||
/>
|
||||
</div>
|
||||
</SidebarMenuButton>
|
||||
</DisclosureTrigger>
|
||||
<DisclosureContent>
|
||||
<div className="flex flex-col gap-1 py-2">
|
||||
{Object.keys(dataFilter[item.name])
|
||||
.sort((a, b) =>
|
||||
sensitiveSort(
|
||||
dataFilter[item.name][a].display_name,
|
||||
dataFilter[item.name][b].display_name,
|
||||
),
|
||||
)
|
||||
.map((SBItemName: string, idx) => (
|
||||
<ShadTooltip
|
||||
content={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.display_name
|
||||
}
|
||||
side="right"
|
||||
key={idx}
|
||||
>
|
||||
<SidebarDraggableComponent
|
||||
sectionName={item.name as string}
|
||||
apiClass={
|
||||
dataFilter[item.name][SBItemName]
|
||||
}
|
||||
icon={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.icon ??
|
||||
item.icon ??
|
||||
"Unknown"
|
||||
}
|
||||
key={idx}
|
||||
onDragStart={(event) =>
|
||||
onDragStart(event, {
|
||||
type: removeCountFromString(
|
||||
SBItemName,
|
||||
),
|
||||
node: dataFilter[item.name][
|
||||
SBItemName
|
||||
],
|
||||
})
|
||||
}
|
||||
color={nodeColors[item.name]}
|
||||
itemName={SBItemName}
|
||||
error={
|
||||
!!dataFilter[item.name][SBItemName]
|
||||
.error
|
||||
}
|
||||
display_name={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.display_name
|
||||
}
|
||||
side="right"
|
||||
key={idx}
|
||||
>
|
||||
<SidebarDraggableComponent
|
||||
sectionName={item.name as string}
|
||||
apiClass={
|
||||
dataFilter[item.name][SBItemName]
|
||||
}
|
||||
icon={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.icon ??
|
||||
item.icon ??
|
||||
"Unknown"
|
||||
}
|
||||
key={idx}
|
||||
onDragStart={(event) =>
|
||||
onDragStart(event, {
|
||||
type: removeCountFromString(
|
||||
SBItemName,
|
||||
),
|
||||
node: dataFilter[item.name][
|
||||
SBItemName
|
||||
],
|
||||
})
|
||||
}
|
||||
color={nodeColors[item.name]}
|
||||
itemName={SBItemName}
|
||||
error={
|
||||
!!dataFilter[item.name][
|
||||
SBItemName
|
||||
].error
|
||||
}
|
||||
display_name={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.display_name
|
||||
}
|
||||
official={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.official === false
|
||||
? false
|
||||
: true
|
||||
}
|
||||
beta={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.beta ?? false
|
||||
}
|
||||
legacy={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.legacy ?? false
|
||||
}
|
||||
/>
|
||||
</ShadTooltip>
|
||||
))}
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
),
|
||||
)}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
official={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.official === false
|
||||
? false
|
||||
: true
|
||||
}
|
||||
beta={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.beta ?? false
|
||||
}
|
||||
legacy={
|
||||
dataFilter[item.name][SBItemName]
|
||||
.legacy ?? false
|
||||
}
|
||||
/>
|
||||
</ShadTooltip>
|
||||
))}
|
||||
</div>
|
||||
</DisclosureContent>
|
||||
</SidebarMenuItem>
|
||||
</Disclosure>
|
||||
),
|
||||
)}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="flex h-full flex-col items-center justify-center p-4 text-center">
|
||||
<ForwardedIconComponent
|
||||
name="Search"
|
||||
className="mb-4 h-8 w-8 text-muted-foreground"
|
||||
/>
|
||||
<h3 className="mb-2 text-lg font-semibold">No results found</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Try adjusting your search or filter to find what you're looking
|
||||
for.
|
||||
<div className="flex h-full flex-col items-center justify-center text-center">
|
||||
<p className="text-sm text-secondary-foreground">
|
||||
No components found.{" "}
|
||||
<a
|
||||
className="cursor-pointer underline underline-offset-4"
|
||||
onClick={handleClearSearch}
|
||||
>
|
||||
Clear your search
|
||||
</a>{" "}
|
||||
or filter and try a different query.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -669,15 +678,24 @@ export function FlowSidebarComponent() {
|
|||
<SidebarFooter className="border-t p-4 py-3">
|
||||
{hasStore && (
|
||||
<SidebarMenuButton asChild>
|
||||
<CustomLink to="/store">
|
||||
<div className="flex items-center gap-2">
|
||||
<CustomLink
|
||||
to="/store"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group/discover"
|
||||
>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<ForwardedIconComponent
|
||||
name="Store"
|
||||
className="h-4 w-4 text-muted-foreground"
|
||||
/>
|
||||
<span className="group-data-[state=open]/collapsible:font-semibold">
|
||||
<span className="flex-1 group-data-[state=open]/collapsible:font-semibold">
|
||||
Discover more components
|
||||
</span>
|
||||
<ForwardedIconComponent
|
||||
name="SquareArrowOutUpRight"
|
||||
className="h-4 w-4 opacity-0 transition-all group-hover/discover:opacity-100"
|
||||
/>
|
||||
</div>
|
||||
</CustomLink>
|
||||
</SidebarMenuButton>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function ShortcutDisplay({
|
|||
{name && <span> {name} </span>}
|
||||
<span
|
||||
className={cn(
|
||||
"flex items-center rounded-sm bg-muted px-1.5 py-[0.1em] text-lg text-muted-foreground",
|
||||
"flex h-5 items-center rounded-sm bg-muted px-1.5 text-lg text-muted-foreground",
|
||||
name && "ml-3",
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ import { useGetFlow } from "@/controllers/API/queries/flows/use-get-flow";
|
|||
import { useGetRefreshFlows } from "@/controllers/API/queries/flows/use-get-refresh-flows";
|
||||
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
|
||||
import useSaveFlow from "@/hooks/flows/use-save-flow";
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import { SaveChangesModal } from "@/modals/saveChangesModal";
|
||||
import useAlertStore from "@/stores/alertStore";
|
||||
import { useTypesStore } from "@/stores/typesStore";
|
||||
import { customStringify } from "@/utils/reactflowUtils";
|
||||
import { useEffect } from "react";
|
||||
import { useBlocker, useParams } from "react-router-dom";
|
||||
import FlowToolbar from "../../components/flowToolbarComponent";
|
||||
import { useDarkStore } from "../../stores/darkStore";
|
||||
import useFlowStore from "../../stores/flowStore";
|
||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||
|
|
@ -160,12 +160,14 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
|||
setCurrentFlow(flow);
|
||||
};
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flow-page-positioning">
|
||||
{currentFlow && (
|
||||
<div className="flex h-full overflow-hidden">
|
||||
<SidebarProvider>
|
||||
<SidebarProvider width="19rem" defaultOpen={!isMobile}>
|
||||
{!view && <FlowSidebarComponent />}
|
||||
<main className="flex flex-1">
|
||||
<div className="h-full w-full">
|
||||
|
|
|
|||
|
|
@ -1267,10 +1267,6 @@
|
|||
@apply flex w-max min-w-10 items-center gap-1 rounded-lg text-foreground;
|
||||
}
|
||||
|
||||
.share-button {
|
||||
@apply relative inline-flex h-full w-full items-center justify-center gap-1.5 rounded px-3 py-1.5 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-accent;
|
||||
}
|
||||
|
||||
.last-output-border {
|
||||
@apply rounded-b-[12px];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,9 +272,10 @@ pre {
|
|||
background-color: hsl(var(--code-background)) !important;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button {
|
||||
[type="search"]:not(:placeholder-shown)::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
background-color: hsl(var(--primary));
|
||||
opacity: 1 !important;
|
||||
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23777'><path d='M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/></svg>");
|
||||
background-size: 20px 20px;
|
||||
height: 20px;
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@
|
|||
--note-indigo: #e0e7ff;
|
||||
--note-emerald: #d1fae5;
|
||||
--note-red: #fee2e2;
|
||||
--error-red:0,86%,97%; /*hsla(0, 86%, 97%)*/
|
||||
--error-red-border: 0,96%,89%; /*hsla(0,96%,89%)*/
|
||||
--error-red: 0, 86%, 97%; /*hsla(0, 86%, 97%)*/
|
||||
--error-red-border: 0, 96%, 89%; /*hsla(0,96%,89%)*/
|
||||
--note-default-opacity: #f1f5f980;
|
||||
--note-indigo-opacity: #312e8180;
|
||||
--note-emerald-opacity: #064e3b80;
|
||||
|
|
@ -159,17 +159,17 @@
|
|||
--background: 240 6% 10%; /* hsl(240, 6%, 10%) */
|
||||
--muted: 240 4% 16%; /* hsl(240, 4%, 16%) */
|
||||
--muted-foreground: 240 5% 65%; /* hsl(240, 5%, 65%) */
|
||||
--card: 0 0% 0%; /* hsl(0, 0, 0%) */
|
||||
--card: 240 6% 10%; /* hsl(240, 6%, 10%) */
|
||||
--card-foreground: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
--popover: 0 0% 0%; /* hsl(0, 0%, 0%) */
|
||||
--popover: 240 6% 10%; /* hsl(240, 6%, 10%) */
|
||||
--popover-foreground: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
--border: 240 4% 16%; /* hsl(240, 4%, 16%) */
|
||||
--input: 240 5% 26%; /* hsl(240, 5%, 26%) */
|
||||
--border: 240 5% 26%; /* hsl(240, 5%, 26%) */
|
||||
--input: 240 5% 34%; /* hsl(240, 5%, 34%) */
|
||||
--primary-foreground: 0 0% 0%; /* hsl(0, 0%, 0%) */
|
||||
--primary: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
--secondary: 0 0% 0%; /* hsl(0, 0%, 0%) */
|
||||
--secondary-foreground: 240 6% 90%; /* hsl(240, 6%, 90%) */
|
||||
--accent: 240 6% 10%; /* hsl(240, 6%, 10%) */
|
||||
--accent: 240 4% 16%; /* hsl(240, 4%, 16%) */
|
||||
--accent-foreground: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
--destructive: 0 84% 60%; /* hsl(0, 84%, 60%) */
|
||||
--destructive-foreground: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
|
|
@ -177,7 +177,7 @@
|
|||
--primary-hover: 240 6% 90%; /* hsl(240, 6%, 90%) */
|
||||
--secondary-hover: 240 4% 16%; /* hsl(240, 4%, 16%) */
|
||||
--placeholder-foreground: 240 4% 46%; /* hsl(240, 4%, 46%) */
|
||||
--canvas: 240 6% 10%; /* hsl(240, 6%, 10%) */
|
||||
--canvas: 0 0% 0%; /* hsl(0, 0%, 0%) */
|
||||
--accent-emerald: 164 86% 16%; /* hsl(164, 86%, 16%) */
|
||||
--accent-emerald-foreground: 158 64% 52%; /* hsl(158, 64%, 52%) */
|
||||
--accent-indigo: 242 25% 34%; /* hsl(242, 25%, 34%) */
|
||||
|
|
@ -188,8 +188,8 @@
|
|||
--tooltip: 0 0% 100%; /* hsl(0, 0%, 100%) */
|
||||
|
||||
--tooltip-foreground: 0 0% 0%; /* hsl(0, 0%, 0%) */
|
||||
--error-red:0,75%,15%; /*hsla(0, 75%, 15%)*/
|
||||
--error-red-border: 0,70%,35%; /*hsla(0,70%,35%)*/
|
||||
--error-red: 0, 75%, 15%; /*hsla(0, 75%, 15%)*/
|
||||
--error-red-border: 0, 70%, 35%; /*hsla(0,70%,35%)*/
|
||||
|
||||
--note-default: #0f172a;
|
||||
--note-indigo: #312e81;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ import {
|
|||
Palette,
|
||||
PanelLeftClose,
|
||||
PanelLeftOpen,
|
||||
PanelRightClose,
|
||||
Paperclip,
|
||||
PaperclipIcon,
|
||||
Pen,
|
||||
|
|
@ -160,6 +161,7 @@ import {
|
|||
Snowflake,
|
||||
Sparkles,
|
||||
Square,
|
||||
SquareArrowOutUpRight,
|
||||
SquarePen,
|
||||
SquarePlay,
|
||||
StickyNote,
|
||||
|
|
@ -432,11 +434,6 @@ export const SIDEBAR_CATEGORIES = [
|
|||
{ display_name: "Agents", name: "agents", icon: "Bot" },
|
||||
{ display_name: "Chains", name: "chains", icon: "Link" },
|
||||
{ display_name: "Loaders", name: "documentloaders", icon: "Paperclip" },
|
||||
{
|
||||
display_name: "Utilities",
|
||||
name: "langchain_utilities",
|
||||
icon: "PocketKnife",
|
||||
},
|
||||
{ display_name: "Link Extractors", name: "link_extractors", icon: "Link2" },
|
||||
{ display_name: "Memories", name: "memories", icon: "Cpu" },
|
||||
{ display_name: "Output Parsers", name: "output_parsers", icon: "Compass" },
|
||||
|
|
@ -452,9 +449,9 @@ export const SIDEBAR_BUNDLES = [
|
|||
{ display_name: "LangChain", name: "langchain_utilities", icon: "LangChain" },
|
||||
{ display_name: "AssemblyAI", name: "assemblyai", icon: "AssemblyAI" },
|
||||
{
|
||||
display_name: "Astra Assistants",
|
||||
display_name: "DataStax",
|
||||
name: "astra_assistants",
|
||||
icon: "Sparkles",
|
||||
icon: "AstraDB",
|
||||
},
|
||||
{ display_name: "Google", name: "google", icon: "Google" },
|
||||
{ display_name: "Firecrawl", name: "firecrawl", icon: "FirecrawlCrawlApi" },
|
||||
|
|
@ -772,6 +769,7 @@ export const nodeIconsLucide: iconsType = {
|
|||
Link,
|
||||
ToyBrick,
|
||||
RefreshCcw,
|
||||
SquareArrowOutUpRight,
|
||||
Combine,
|
||||
TerminalIcon,
|
||||
TerminalSquare,
|
||||
|
|
@ -789,6 +787,7 @@ export const nodeIconsLucide: iconsType = {
|
|||
Delete,
|
||||
Command,
|
||||
ArrowBigUp,
|
||||
PanelRightClose,
|
||||
Dot,
|
||||
StickyNote,
|
||||
note: StickyNote,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ test("user must see on handle click the possibility connections - LLMChain", asy
|
|||
await expect(page.getByTestId("disclosure-data")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-helpers")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-vector stores")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-utilities")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-prototypes")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-retrievers")).toBeVisible();
|
||||
await expect(page.getByTestId("disclosure-embeddings")).toBeVisible();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue