fix: update nav bar UI, changed user menu to use shadcn dropdown, fix responsivity issues (#4454)
* Updated saved color * Removed selection from header / * hide text from 1200px * Updated github star style * Fixed hover state on account menu * Fix misalignment of store * Changed user menu to use dropdown menu from shadcn * Fixed notification dot * Change mobile responsivity * Fixed flow settings name * Implement opening the sidebar when hitting / * Fixed code opening when hitting space on sidebar * Fixed errors with tests
This commit is contained in:
parent
a4863bbe57
commit
6761df6110
18 changed files with 120 additions and 166 deletions
|
|
@ -98,7 +98,11 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
return <div className="truncate">Saving...</div>;
|
return <div className="truncate">Saving...</div>;
|
||||||
}
|
}
|
||||||
// return savedText;
|
// return savedText;
|
||||||
return <div className="truncate text-[#059669]">Saved</div>;
|
return (
|
||||||
|
<div className="shrink-0 text-xs font-medium text-accent-emerald-foreground">
|
||||||
|
Saved
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
|
|
@ -111,10 +115,10 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
useHotkeys(changes, handleSave, { preventDefault: true });
|
useHotkeys(changes, handleSave, { preventDefault: true });
|
||||||
|
|
||||||
return currentFlow && onFlowPage ? (
|
return currentFlow && onFlowPage ? (
|
||||||
<div className="flex items-baseline gap-2 truncate">
|
<div className="flex items-center justify-center gap-2 truncate">
|
||||||
<div className="header-menu-bar w-full justify-end truncate">
|
<div className="header-menu-bar hidden justify-end truncate md:flex">
|
||||||
{currentFolder?.name && (
|
{currentFolder?.name && (
|
||||||
<div className="flex hidden truncate md:flex">
|
<div className="hidden truncate md:flex">
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer truncate text-muted-foreground hover:text-primary"
|
className="cursor-pointer truncate text-muted-foreground hover:text-primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
@ -126,11 +130,11 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden w-fit font-normal text-muted-foreground md:flex">
|
<div className="hidden w-fit shrink-0 select-none font-normal text-muted-foreground md:flex">
|
||||||
/
|
/
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-fit truncate text-sm sm:overflow-visible sm:whitespace-normal">
|
<div className="w-fit overflow-hidden truncate text-sm sm:whitespace-normal">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<div className="header-menu-bar-display-2 group truncate">
|
<div className="header-menu-bar-display-2 group truncate">
|
||||||
|
|
@ -170,7 +174,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
>
|
>
|
||||||
<IconComponent name="Settings2" className="header-menu-options" />
|
<IconComponent name="Settings2" className="header-menu-options" />
|
||||||
Settings
|
Flow Settings
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{!autoSaving && (
|
{!autoSaving && (
|
||||||
<DropdownMenuItem onClick={handleSave} className="cursor-pointer">
|
<DropdownMenuItem onClick={handleSave} className="cursor-pointer">
|
||||||
|
|
@ -279,7 +283,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
></FlowSettingsModal>
|
></FlowSettingsModal>
|
||||||
<FlowLogsModal open={openLogs} setOpen={setOpenLogs}></FlowLogsModal>
|
<FlowLogsModal open={openLogs} setOpen={setOpenLogs}></FlowLogsModal>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden w-full items-center truncate sm:flex">
|
<div className="hidden shrink-0 items-center sm:flex">
|
||||||
{!autoSaving && (
|
{!autoSaving && (
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,10 @@ export const GithubStarComponent = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ShadTooltip content="Go to Github repo" side="bottom" styleClasses="z-10">
|
<ShadTooltip content="Go to Github repo" side="bottom" styleClasses="z-10">
|
||||||
<div className="header-github-link-box gap-1 bg-muted hover:bg-zinc-200 dark:bg-zinc-900 dark:hover:bg-zinc-800">
|
<div className="group inline-flex h-8 items-center justify-center gap-1 rounded-md border bg-muted px-2 pr-0 hover:border-input hover:bg-secondary-hover">
|
||||||
<FaGithub className="h-4 w-4 text-black dark:text-[white]" />
|
<FaGithub className="h-4 w-4" />
|
||||||
<div className="hidden text-xs font-semibold text-black dark:text-[white] lg:block">
|
<div className="hidden text-xs font-semibold lg:block">Star</div>
|
||||||
Star
|
<div className="-mr-px ml-1 flex h-8 items-center justify-center rounded-md rounded-l-none border bg-background px-2 text-xs font-semibold text-secondary-foreground group-hover:border-input">
|
||||||
</div>
|
|
||||||
<div className="header-github-display text-xs font-semibold text-black dark:text-[white]">
|
|
||||||
{stars.toLocaleString() ?? 0}
|
{stars.toLocaleString() ?? 0}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,110 +1,68 @@
|
||||||
import ForwardedIconComponent from "@/components/genericIconComponent";
|
import ForwardedIconComponent from "@/components/genericIconComponent";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import {
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { cn } from "@/utils/utils";
|
||||||
import { ChevronsUpDown } from "lucide-react";
|
import { ChevronsUpDown } from "lucide-react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Fragment } from "react/jsx-runtime";
|
|
||||||
import ExpandMoreIcon from "../../assets/ExpandMoreIcon.svg?react";
|
|
||||||
import ScienceOutlinedIcon from "../../assets/ScienceOutlinedIcon.svg?react";
|
|
||||||
|
|
||||||
export const HeaderMenu = ({ children }) => (
|
export const HeaderMenu = ({ children }) => (
|
||||||
<Menu as="div" className="relative text-left">
|
<DropdownMenu>{children}</DropdownMenu>
|
||||||
{children}
|
|
||||||
</Menu>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const HeaderMenuToggle = ({ children }) => (
|
export const HeaderMenuToggle = ({ children }) => (
|
||||||
<Menu.Button className="inline-flex w-full items-center justify-center gap-1 rounded-md px-2 py-2 text-sm font-medium text-white hover:bg-accent hover:text-accent-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75">
|
<DropdownMenuTrigger className="group inline-flex w-full items-center justify-center gap-1 rounded-md px-2 py-2 pr-0">
|
||||||
|
<div className="flex items-center gap-1 rounded-full group-hover:bg-muted">
|
||||||
{children}
|
{children}
|
||||||
<ChevronsUpDown
|
<ChevronsUpDown
|
||||||
className="text-zinc-500"
|
className="mr-2 text-muted-foreground group-hover:text-foreground"
|
||||||
size={"15px"}
|
size={"15px"}
|
||||||
strokeWidth={"2px"}
|
strokeWidth={"2px"}
|
||||||
/>
|
/>
|
||||||
</Menu.Button>
|
</div>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const HeaderMenuSelector = ({
|
|
||||||
Icon,
|
|
||||||
loading,
|
|
||||||
children,
|
|
||||||
Preview,
|
|
||||||
}: React.PropsWithChildren<{
|
|
||||||
Icon?: React.FunctionComponent<
|
|
||||||
React.SVGProps<SVGSVGElement> & {
|
|
||||||
title?: string | undefined;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
loading?: boolean;
|
|
||||||
Preview?: boolean;
|
|
||||||
}>) => (
|
|
||||||
<Menu.Button className="group inline-flex h-8 w-full items-center justify-center gap-2 rounded-md border border-solid border-gray-300 px-3 py-1.5 text-sm hover:bg-gray-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75 dark:border-zinc-700 dark:hover:bg-zinc-800">
|
|
||||||
{Icon ? <Icon className="h-4 w-4 fill-black dark:fill-zinc-400" /> : null}
|
|
||||||
{loading ? (
|
|
||||||
<Skeleton className="min-w-28 bg-gray-100 text-left"> </Skeleton>
|
|
||||||
) : (
|
|
||||||
<span className="min-w-0 max-w-48 overflow-x-clip text-ellipsis text-nowrap font-semibold">
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{Preview ? (
|
|
||||||
<ScienceOutlinedIcon className="h-5 w-6 rounded border bg-zinc-100 fill-gray-500 group-hover:bg-purple-100 group-hover:fill-purple-700 dark:bg-zinc-800 dark:fill-zinc-400 dark:group-hover:bg-purple-500 dark:group-hover:fill-purple-100" />
|
|
||||||
) : null}
|
|
||||||
<ExpandMoreIcon className="fill-gray-400 group-hover:fill-black dark:group-hover:fill-zinc-400" />
|
|
||||||
</Menu.Button>
|
|
||||||
);
|
|
||||||
|
|
||||||
const BASE_ITEM_STYLES =
|
|
||||||
"group flex w-full items-center justify-between h-[40px] my-1 rounded-md px-3 text-sm text-gray-900 dark:text-[white] dark:hover:bg-zinc-800 hover:bg-gray-100";
|
|
||||||
|
|
||||||
export const HeaderMenuItemLink = ({
|
export const HeaderMenuItemLink = ({
|
||||||
href = "#",
|
href = "#",
|
||||||
selected = false,
|
|
||||||
children,
|
children,
|
||||||
newPage = false,
|
newPage = false,
|
||||||
icon = "external-link",
|
icon = "external-link",
|
||||||
}) => (
|
}) => (
|
||||||
<Menu.Item>
|
<DropdownMenuItem className="cursor-pointer p-3 px-4" asChild>
|
||||||
{({ active }) => (
|
|
||||||
<a
|
<a
|
||||||
className={`group ${selected ? "bg-gray-50" : ""} ${BASE_ITEM_STYLES}`}
|
|
||||||
href={href}
|
href={href}
|
||||||
|
className="group flex w-full items-center justify-between"
|
||||||
{...(newPage ? { rel: "noreferrer", target: "_blank" } : {})}
|
{...(newPage ? { rel: "noreferrer", target: "_blank" } : {})}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{icon && (
|
{icon && (
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name={icon}
|
name={icon}
|
||||||
className="side-bar-button-size hidden h-[18px] w-[18px] group-hover:block" // Use group-hover:block to show on hover
|
className="side-bar-button-size h-[18px] w-[18px] opacity-0 transition-all group-hover:opacity-100"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
)}
|
</DropdownMenuItem>
|
||||||
</Menu.Item>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const HeaderMenuItemButton = ({
|
export const HeaderMenuItemButton = ({ icon = "", onClick, children }) => (
|
||||||
icon = "",
|
<DropdownMenuItem
|
||||||
onClick,
|
className="group flex cursor-pointer items-center justify-between p-3 px-4"
|
||||||
selected = false,
|
|
||||||
children,
|
|
||||||
}) => (
|
|
||||||
<Menu.Item>
|
|
||||||
{({ active }) => (
|
|
||||||
<button
|
|
||||||
className={`${selected ? "bg-gray-50 dark:bg-zinc-800" : ""} ${BASE_ITEM_STYLES}`}
|
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{icon && (
|
{icon && (
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name={icon}
|
name={icon}
|
||||||
className="side-bar-button-size hidden h-[18px] w-[18px] group-hover:block" // Use group-hover:block to show on hover
|
className="side-bar-button-size h-[18px] w-[18px] opacity-0 transition-all group-hover:opacity-100"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</button>
|
</DropdownMenuItem>
|
||||||
)}
|
|
||||||
</Menu.Item>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const HeaderMenuItems = ({
|
export const HeaderMenuItems = ({
|
||||||
|
|
@ -113,28 +71,16 @@ export const HeaderMenuItems = ({
|
||||||
}: React.PropsWithChildren<{ position?: "left" | "right" }>) => {
|
}: React.PropsWithChildren<{ position?: "left" | "right" }>) => {
|
||||||
const positionClass = position === "left" ? "left-0" : "right-0";
|
const positionClass = position === "left" ? "left-0" : "right-0";
|
||||||
return (
|
return (
|
||||||
<Transition
|
<DropdownMenuContent className={cn("w-[20rem] p-1", positionClass)}>
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="transform opacity-0 scale-95"
|
|
||||||
enterTo="transform opacity-100 scale-100"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
|
||||||
leaveTo="transform opacity-0 scale-95"
|
|
||||||
>
|
|
||||||
<Menu.Items
|
|
||||||
className={`absolute dark:bg-black ${positionClass} z-[999] mt-2 w-[20rem] origin-top-right rounded-md border bg-[white] shadow-lg ring-1 ring-black/5 focus:outline-none dark:border-zinc-800`}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</Menu.Items>
|
</DropdownMenuContent>
|
||||||
</Transition>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HeaderMenuItemsSection = ({ children }) => (
|
export const HeaderMenuItemsSection = ({ children }) => (
|
||||||
<>
|
<>
|
||||||
<div className="px-1">{children}</div>
|
{children}
|
||||||
<hr className="border-gray-200 last:hidden dark:border-zinc-700" />
|
<DropdownMenuSeparator className="last:hidden" />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export const ThemeButtons = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative ml-auto inline-flex rounded-full border border-zinc-200 p-0.5 dark:border-zinc-700">
|
<div className="relative ml-auto inline-flex rounded-full border border-border p-0.5">
|
||||||
{/* Sliding Indicator - Behind the Buttons */}
|
{/* Sliding Indicator - Behind the Buttons */}
|
||||||
<div
|
<div
|
||||||
className={`absolute bottom-0.5 left-[1px] top-0.5 w-[30%] rounded-full bg-amber-400 ${
|
className={`absolute bottom-0.5 left-[1px] top-0.5 w-[30%] rounded-full bg-amber-400 ${
|
||||||
|
|
@ -53,12 +53,12 @@ export const ThemeButtons = () => {
|
||||||
unstyled
|
unstyled
|
||||||
className={`relative z-10 inline-flex items-center rounded-full px-1 ${
|
className={`relative z-10 inline-flex items-center rounded-full px-1 ${
|
||||||
selectedTheme === "light"
|
selectedTheme === "light"
|
||||||
? "text-black dark:text-[black]"
|
? "text-foreground"
|
||||||
: "hover:text-black dark:text-[white] dark:hover:bg-amber-400 dark:hover:text-[black]"
|
: "text-foreground hover:text-background dark:hover:bg-amber-400"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleThemeChange("light")}
|
onClick={() => handleThemeChange("light")}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent name="sun" className="w-4" />
|
<ForwardedIconComponent name="Sun" className="w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* Dark Theme Button */}
|
{/* Dark Theme Button */}
|
||||||
|
|
@ -66,12 +66,12 @@ export const ThemeButtons = () => {
|
||||||
unstyled
|
unstyled
|
||||||
className={`relative z-10 mx-1 inline-flex items-center rounded-full px-1 ${
|
className={`relative z-10 mx-1 inline-flex items-center rounded-full px-1 ${
|
||||||
selectedTheme === "dark"
|
selectedTheme === "dark"
|
||||||
? "text-black dark:text-[black] dark:hover:bg-purple-400 dark:hover:text-[black]"
|
? "text-background dark:hover:bg-purple-400"
|
||||||
: "hover:bg-purple-400 hover:text-[black] hover:text-[white] dark:hover:text-[black]"
|
: "text-foreground hover:bg-purple-400 hover:text-background"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleThemeChange("dark")}
|
onClick={() => handleThemeChange("dark")}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent name="moon" className="w-4" />
|
<ForwardedIconComponent name="Moon" className="w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* System Theme Button */}
|
{/* System Theme Button */}
|
||||||
|
|
@ -79,12 +79,12 @@ export const ThemeButtons = () => {
|
||||||
unstyled
|
unstyled
|
||||||
className={`relative z-10 inline-flex items-center rounded-full px-1 ${
|
className={`relative z-10 inline-flex items-center rounded-full px-1 ${
|
||||||
selectedTheme === "system"
|
selectedTheme === "system"
|
||||||
? "text-black dark:bg-[white] dark:text-[black]"
|
? "bg-foreground text-background"
|
||||||
: "hover:bg-[black] hover:text-[white] dark:hover:bg-[white] dark:hover:text-[black]"
|
: "hover:bg-foreground hover:text-background"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleThemeChange("system")}
|
onClick={() => handleThemeChange("system")}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent name="monitor" className="w-4" />
|
<ForwardedIconComponent name="Monitor" className="w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ export default function AppHeader(): JSX.Element {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed left-0 top-0 z-[1] flex h-[62px] w-full items-center border-b px-5 py-2.5 dark:bg-background">
|
<div className="z-[1] flex h-[62px] w-full items-center justify-between gap-2 border-b px-5 py-2.5 dark:bg-background">
|
||||||
{/* Left Section */}
|
{/* Left Section */}
|
||||||
<div className={`absolute left-[20px] flex gap-2`}>
|
<div className={`flex gap-2`}>
|
||||||
<Button
|
<Button
|
||||||
unstyled
|
unstyled
|
||||||
onClick={() => navigate("/")}
|
onClick={() => navigate("/")}
|
||||||
|
|
@ -73,17 +73,17 @@ export default function AppHeader(): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Middle Section */}
|
{/* Middle Section */}
|
||||||
<div className="absolute left-[225px] right-[225px] truncate md:left-[230px] md:right-[230px] lg:left-[350px] lg:right-[350px] xl:left-[350px] xl:right-[350px] 2xl:left-[500px] 2xl:right-[500px]">
|
<div className="w-full flex-1 truncate md:max-w-[57%] lg:absolute lg:left-1/2 lg:max-w-[43%] lg:-translate-x-1/2 xl:max-w-[31%]">
|
||||||
<FlowMenu />
|
<FlowMenu />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right Section */}
|
{/* Right Section */}
|
||||||
<div className={`absolute right-[20px] flex gap-2`}>
|
<div className={`flex items-center gap-2`}>
|
||||||
{!ENABLE_DATASTAX_LANGFLOW && (
|
{!ENABLE_DATASTAX_LANGFLOW && (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
unstyled
|
unstyled
|
||||||
className="flex hidden items-center whitespace-nowrap 2xl:inline"
|
className="hidden items-center whitespace-nowrap 2xl:inline"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
window.open("https://github.com/langflow-ai/langflow", "_blank")
|
window.open("https://github.com/langflow-ai/langflow", "_blank")
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,9 @@ export default function AppHeader(): JSX.Element {
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={
|
className={
|
||||||
notificationCenter ? `header-notifications-dot` : "hidden"
|
notificationCenter
|
||||||
|
? `absolute left-[31px] top-[10px] block h-1 w-1 rounded-full bg-destructive`
|
||||||
|
: "hidden"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
@ -121,7 +123,7 @@ export default function AppHeader(): JSX.Element {
|
||||||
className="side-bar-button-size h-[18px] w-[18px]"
|
className="side-bar-button-size h-[18px] w-[18px]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span className="hidden whitespace-nowrap lg:inline">
|
<span className="hidden whitespace-nowrap xl:inline">
|
||||||
Notifications
|
Notifications
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -136,7 +138,7 @@ export default function AppHeader(): JSX.Element {
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className={`flex items-center text-sm font-medium ${lastPath === "store" ? "bg-accent text-accent-foreground" : ""}`}
|
className={` ${lastPath === "store" ? "bg-accent text-accent-foreground" : ""}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/store");
|
navigate("/store");
|
||||||
}}
|
}}
|
||||||
|
|
@ -146,7 +148,7 @@ export default function AppHeader(): JSX.Element {
|
||||||
name="Store"
|
name="Store"
|
||||||
className="side-bar-button-size h-[18px] w-[18px]"
|
className="side-bar-button-size h-[18px] w-[18px]"
|
||||||
/>
|
/>
|
||||||
<span className="hidden whitespace-nowrap lg:inline">
|
<span className="hidden whitespace-nowrap xl:inline">
|
||||||
Store
|
Store
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ const DropdownMenuSeparator = React.forwardRef<
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => (
|
||||||
<DropdownMenuPrimitive.Separator
|
<DropdownMenuPrimitive.Separator
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export function DashboardWrapperPage() {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-full flex-col">
|
<div className="flex h-screen w-full flex-col">
|
||||||
<AppHeader />
|
<AppHeader />
|
||||||
<div className="mt-[62px] flex h-[calc(100vh-62px)] w-full flex-row">
|
<div className="flex h-full w-full flex-row">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { useHotkeys } from "react-hotkeys-hook"; // Import useHotkeys
|
||||||
|
|
||||||
import ForwardedIconComponent from "@/components/genericIconComponent";
|
import ForwardedIconComponent from "@/components/genericIconComponent";
|
||||||
import ShadTooltip from "@/components/shadTooltipComponent";
|
import ShadTooltip from "@/components/shadTooltipComponent";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Disclosure,
|
Disclosure,
|
||||||
|
|
@ -25,9 +24,8 @@ import {
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarMenuSkeleton,
|
SidebarMenuSkeleton,
|
||||||
SidebarTrigger,
|
SidebarTrigger,
|
||||||
|
useSidebar,
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
import { Switch } from "@/components/ui/switch";
|
|
||||||
import { CustomLink } from "@/customization/components/custom-link";
|
|
||||||
import { useAddComponent } from "@/hooks/useAddComponent";
|
import { useAddComponent } from "@/hooks/useAddComponent";
|
||||||
import { useStoreStore } from "@/stores/storeStore";
|
import { useStoreStore } from "@/stores/storeStore";
|
||||||
import { checkChatInput } from "@/utils/reactflowUtils";
|
import { checkChatInput } from "@/utils/reactflowUtils";
|
||||||
|
|
@ -36,7 +34,6 @@ import {
|
||||||
SIDEBAR_BUNDLES,
|
SIDEBAR_BUNDLES,
|
||||||
SIDEBAR_CATEGORIES,
|
SIDEBAR_CATEGORIES,
|
||||||
} from "@/utils/styleUtils";
|
} from "@/utils/styleUtils";
|
||||||
import { removeCountFromString } from "@/utils/utils";
|
|
||||||
import { cloneDeep } from "lodash";
|
import { cloneDeep } from "lodash";
|
||||||
import useAlertStore from "../../../../stores/alertStore";
|
import useAlertStore from "../../../../stores/alertStore";
|
||||||
import useFlowStore from "../../../../stores/flowStore";
|
import useFlowStore from "../../../../stores/flowStore";
|
||||||
|
|
@ -47,7 +44,6 @@ import sensitiveSort from "../extraSidebarComponent/utils/sensitive-sort";
|
||||||
import ShortcutDisplay from "../nodeToolbarComponent/shortcutDisplay";
|
import ShortcutDisplay from "../nodeToolbarComponent/shortcutDisplay";
|
||||||
import NoResultsMessage from "./components/emptySearchComponent";
|
import NoResultsMessage from "./components/emptySearchComponent";
|
||||||
import FeatureToggles from "./components/featureTogglesComponent";
|
import FeatureToggles from "./components/featureTogglesComponent";
|
||||||
import SidebarDraggableComponent from "./components/sidebarDraggableComponent";
|
|
||||||
import SidebarMenuButtons from "./components/sidebarFooterButtons";
|
import SidebarMenuButtons from "./components/sidebarFooterButtons";
|
||||||
import SidebarItemsList from "./components/sidebarItemsList";
|
import SidebarItemsList from "./components/sidebarItemsList";
|
||||||
import { applyBetaFilter } from "./helpers/apply-beta-filter";
|
import { applyBetaFilter } from "./helpers/apply-beta-filter";
|
||||||
|
|
@ -85,9 +81,13 @@ export function FlowSidebarComponent() {
|
||||||
const [showBeta, setShowBeta] = useState(true);
|
const [showBeta, setShowBeta] = useState(true);
|
||||||
const [showLegacy, setShowLegacy] = useState(false);
|
const [showLegacy, setShowLegacy] = useState(false);
|
||||||
|
|
||||||
|
const { setOpen } = useSidebar();
|
||||||
|
|
||||||
useHotkeys("/", (event) => {
|
useHotkeys("/", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
searchInputRef.current?.focus();
|
searchInputRef.current?.focus();
|
||||||
|
|
||||||
|
setOpen(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
|
|
@ -268,7 +268,11 @@ export function FlowSidebarComponent() {
|
||||||
const chatInputAdded = checkChatInput(nodes);
|
const chatInputAdded = checkChatInput(nodes);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar collapsible="offcanvas" data-testid="shad-sidebar">
|
<Sidebar
|
||||||
|
collapsible="offcanvas"
|
||||||
|
data-testid="shad-sidebar"
|
||||||
|
className="noflow"
|
||||||
|
>
|
||||||
<SidebarHeader className="flex w-full flex-col gap-4 p-4 pb-1">
|
<SidebarHeader className="flex w-full flex-col gap-4 p-4 pb-1">
|
||||||
<Disclosure open={showConfig} onOpenChange={setShowConfig}>
|
<Disclosure open={showConfig} onOpenChange={setShowConfig}>
|
||||||
<div className="flex w-full items-center gap-2">
|
<div className="flex w-full items-center gap-2">
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ const HeaderComponent = ({
|
||||||
key={type}
|
key={type}
|
||||||
unstyled
|
unstyled
|
||||||
id={`${type}-btn`}
|
id={`${type}-btn`}
|
||||||
|
data-testid={`${type}-btn`}
|
||||||
onClick={() => setFlowType(type as "flows" | "components")}
|
onClick={() => setFlowType(type as "flows" | "components")}
|
||||||
className={`border-b ${
|
className={`border-b ${
|
||||||
flowType === type
|
flowType === type
|
||||||
|
|
|
||||||
|
|
@ -606,18 +606,12 @@
|
||||||
.header-github-link:hover {
|
.header-github-link:hover {
|
||||||
@apply hover:bg-accent hover:text-accent-foreground;
|
@apply hover:bg-accent hover:text-accent-foreground;
|
||||||
}
|
}
|
||||||
.header-github-display {
|
|
||||||
@apply -mr-px ml-1 flex h-8 items-center justify-center rounded-md rounded-l-none border bg-[white] px-2 text-sm dark:bg-[black];
|
|
||||||
}
|
|
||||||
.header-notifications-box {
|
.header-notifications-box {
|
||||||
@apply fixed left-0 top-0 h-screen w-screen;
|
@apply fixed left-0 top-0 h-screen w-screen;
|
||||||
}
|
}
|
||||||
.header-notifications {
|
.header-notifications {
|
||||||
@apply absolute right-[3px] h-1.5 w-1.5 rounded-full bg-destructive;
|
@apply absolute right-[3px] h-1.5 w-1.5 rounded-full bg-destructive;
|
||||||
}
|
}
|
||||||
.header-notifications-dot {
|
|
||||||
@apply absolute left-[33px] top-[9px] block h-1.5 w-1.5 rounded-full bg-destructive dark:bg-red-500;
|
|
||||||
}
|
|
||||||
.input-component-div {
|
.input-component-div {
|
||||||
@apply pointer-events-none relative cursor-not-allowed;
|
@apply pointer-events-none relative cursor-not-allowed;
|
||||||
}
|
}
|
||||||
|
|
@ -1272,7 +1266,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-wrapper {
|
.toolbar-wrapper {
|
||||||
@apply flex items-center gap-1 rounded-xl border border-border bg-background p-1 shadow-sm h-10;
|
@apply flex h-10 items-center gap-1 rounded-xl border border-border bg-background p-1 shadow-sm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,5 @@
|
||||||
--accent-indigo: 229.7 93.5% 81.8%;
|
--accent-indigo: 229.7 93.5% 81.8%;
|
||||||
--accent-indigo-foreground: 243.4 75.4% 58.6%;
|
--accent-indigo-foreground: 243.4 75.4% 58.6%;
|
||||||
--node-ring: 240 6% 90%;
|
--node-ring: 240 6% 90%;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ import {
|
||||||
MessagesSquare,
|
MessagesSquare,
|
||||||
Minimize2,
|
Minimize2,
|
||||||
Minus,
|
Minus,
|
||||||
|
Monitor,
|
||||||
|
Moon,
|
||||||
MoonIcon,
|
MoonIcon,
|
||||||
MoreHorizontal,
|
MoreHorizontal,
|
||||||
Network,
|
Network,
|
||||||
|
|
@ -166,6 +168,7 @@ import {
|
||||||
SquarePlay,
|
SquarePlay,
|
||||||
StickyNote,
|
StickyNote,
|
||||||
Store,
|
Store,
|
||||||
|
Sun,
|
||||||
SunIcon,
|
SunIcon,
|
||||||
Table,
|
Table,
|
||||||
TerminalIcon,
|
TerminalIcon,
|
||||||
|
|
@ -797,6 +800,9 @@ export const nodeIconsLucide: iconsType = {
|
||||||
FolderPlusIcon,
|
FolderPlusIcon,
|
||||||
PaperclipIcon,
|
PaperclipIcon,
|
||||||
Settings,
|
Settings,
|
||||||
|
Monitor,
|
||||||
|
Moon,
|
||||||
|
Sun,
|
||||||
PanelLeftClose,
|
PanelLeftClose,
|
||||||
PanelLeftOpen,
|
PanelLeftOpen,
|
||||||
ArrowUpRight,
|
ArrowUpRight,
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ const config = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extend: {
|
extend: {
|
||||||
|
screens: {
|
||||||
|
xl: "1200px",
|
||||||
|
"2xl": "1400px",
|
||||||
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
wiggle: {
|
wiggle: {
|
||||||
"0%, 100%": { transform: "scale(100%)" },
|
"0%, 100%": { transform: "scale(100%)" },
|
||||||
|
|
|
||||||
|
|
@ -182,11 +182,7 @@ test("search components", async ({ page }) => {
|
||||||
await page.getByText("Exit", { exact: true }).click();
|
await page.getByText("Exit", { exact: true }).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
await page
|
await page.getByTestId("components-btn").click();
|
||||||
.getByText("Components", {
|
|
||||||
exact: true,
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await page.getByPlaceholder("Search components").fill("Chat Input");
|
await page.getByPlaceholder("Search components").fill("Chat Input");
|
||||||
await page.getByText("Chat Input", { exact: true }).isVisible();
|
await page.getByText("Chat Input", { exact: true }).isVisible();
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ test("when auto_login is false, admin can CRUD user's and should see just your o
|
||||||
await page.getByTestId("zoom_out").click();
|
await page.getByTestId("zoom_out").click();
|
||||||
|
|
||||||
await page.getByTestId("flow-configuration-button").click();
|
await page.getByTestId("flow-configuration-button").click();
|
||||||
await page.getByText("Settings", { exact: true }).last().click();
|
await page.getByText("Flow Settings", { exact: true }).last().click();
|
||||||
|
|
||||||
await page.getByPlaceholder("Flow Name").fill(randomFlowName);
|
await page.getByPlaceholder("Flow Name").fill(randomFlowName);
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ test("when auto_login is false, admin can CRUD user's and should see just your o
|
||||||
await page.getByTestId("zoom_out").click();
|
await page.getByTestId("zoom_out").click();
|
||||||
|
|
||||||
await page.getByTestId("flow-configuration-button").click();
|
await page.getByTestId("flow-configuration-button").click();
|
||||||
await page.getByText("Settings", { exact: true }).last().click();
|
await page.getByText("Flow Settings", { exact: true }).last().click();
|
||||||
|
|
||||||
await page.getByPlaceholder("Flow Name").fill(secondRandomFlowName);
|
await page.getByPlaceholder("Flow Name").fill(secondRandomFlowName);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ test("should share component with share button", async ({ page }) => {
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
const flowName = await page.getByTestId("flow_name").innerText();
|
const flowName = await page.getByTestId("flow_name").innerText();
|
||||||
await page.getByTestId("flow_name").click();
|
await page.getByTestId("flow_name").click();
|
||||||
await page.getByText("Settings").click();
|
await page.getByText("Flow Settings").click();
|
||||||
const flowDescription = await page
|
const flowDescription = await page
|
||||||
.getByPlaceholder("Flow description")
|
.getByPlaceholder("Flow description")
|
||||||
.inputValue();
|
.inputValue();
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ test("should be able to move flow from folder, rename it and be displayed on cor
|
||||||
await page.getByTestId("fit_view").click();
|
await page.getByTestId("fit_view").click();
|
||||||
|
|
||||||
await page.getByTestId("flow-configuration-button").click();
|
await page.getByTestId("flow-configuration-button").click();
|
||||||
await page.getByText("Settings").click();
|
await page.getByText("Flow Settings").click();
|
||||||
await page.getByPlaceholder("Flow name").fill(randomName);
|
await page.getByPlaceholder("Flow name").fill(randomName);
|
||||||
await page.getByText("Save").last().click();
|
await page.getByText("Save").last().click();
|
||||||
await page.getByTestId("icon-ChevronLeft").last().click();
|
await page.getByTestId("icon-ChevronLeft").last().click();
|
||||||
|
|
@ -89,7 +89,7 @@ test("should be able to move flow from folder, rename it and be displayed on cor
|
||||||
await page.getByTestId(`card-${randomName}`).first().click();
|
await page.getByTestId(`card-${randomName}`).first().click();
|
||||||
|
|
||||||
await page.getByTestId("flow-configuration-button").click();
|
await page.getByTestId("flow-configuration-button").click();
|
||||||
await page.getByText("Settings").click();
|
await page.getByText("Flow Settings").click();
|
||||||
await page.getByPlaceholder("Flow name").fill(secondRandomName);
|
await page.getByPlaceholder("Flow name").fill(secondRandomName);
|
||||||
await page.getByText("Save").last().click();
|
await page.getByText("Save").last().click();
|
||||||
await page.getByTestId("icon-ChevronLeft").last().click();
|
await page.getByTestId("icon-ChevronLeft").last().click();
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ test("flowSettings", async ({ page }) => {
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
await page.getByTestId("flow_name").click();
|
await page.getByTestId("flow_name").click();
|
||||||
await page.getByText("Settings").first().click();
|
await page.getByText("Flow Settings").first().click();
|
||||||
await page
|
await page
|
||||||
.getByPlaceholder("Flow name")
|
.getByPlaceholder("Flow name")
|
||||||
.fill(
|
.fill(
|
||||||
|
|
@ -56,7 +56,7 @@ test("flowSettings", async ({ page }) => {
|
||||||
await page.getByText("Changes saved successfully").isVisible();
|
await page.getByText("Changes saved successfully").isVisible();
|
||||||
|
|
||||||
await page.getByTestId("flow_name").click();
|
await page.getByTestId("flow_name").click();
|
||||||
await page.getByText("Settings").first().click();
|
await page.getByText("Flow Settings").first().click();
|
||||||
|
|
||||||
const flowName = await page.getByPlaceholder("Flow name").inputValue();
|
const flowName = await page.getByPlaceholder("Flow name").inputValue();
|
||||||
const flowDescription = await page
|
const flowDescription = await page
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue