Changes to the menu structure

This commit is contained in:
Lucas Oliveira 2023-06-07 19:44:52 -03:00
commit 62b33a19dc
6 changed files with 391 additions and 86 deletions

View file

@ -14,6 +14,7 @@
"@heroicons/react": "^2.0.15",
"@mui/material": "^5.11.9",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-menubar": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
@ -1559,6 +1560,38 @@
}
}
},
"node_modules/@radix-ui/react-menubar": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.0.3.tgz",
"integrity": "sha512-GqjdxzYCjjKhcgEODDP8SrYfbWNh/Hm3lyuFkP5Q5IbX0QfXklLF1o1AqA3oTV2kulUgN/kOZVS92hIIShEgpA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-collection": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-menu": "2.0.5",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-roving-focus": "1.0.4",
"@radix-ui/react-use-controllable-state": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popper": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz",

View file

@ -9,6 +9,7 @@
"@heroicons/react": "^2.0.15",
"@mui/material": "^5.11.9",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-menubar": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",

View file

@ -0,0 +1,236 @@
"use client";
import * as React from "react";
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "../../utils";
const MenubarMenu = MenubarPrimitive.Menu;
const MenubarGroup = MenubarPrimitive.Group;
const MenubarPortal = MenubarPrimitive.Portal;
const MenubarSub = MenubarPrimitive.Sub;
const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
const Menubar = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Root
ref={ref}
className={cn(
"flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
className
)}
{...props}
/>
));
Menubar.displayName = MenubarPrimitive.Root.displayName;
const MenubarTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Trigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
className
)}
{...props}
/>
));
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
const MenubarSubTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<MenubarPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
inset && "pl-8",
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</MenubarPrimitive.SubTrigger>
));
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
const MenubarSubContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
className
)}
{...props}
/>
));
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
const MenubarContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
>(
(
{ className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
ref
) => (
<MenubarPrimitive.Portal>
<MenubarPrimitive.Content
ref={ref}
align={align}
alignOffset={alignOffset}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in slide-in-from-top-1",
className
)}
{...props}
/>
</MenubarPrimitive.Portal>
)
);
MenubarContent.displayName = MenubarPrimitive.Content.displayName;
const MenubarItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...props}
/>
));
MenubarItem.displayName = MenubarPrimitive.Item.displayName;
const MenubarCheckboxItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<MenubarPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</MenubarPrimitive.ItemIndicator>
</span>
{children}
</MenubarPrimitive.CheckboxItem>
));
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
const MenubarRadioItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<MenubarPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</MenubarPrimitive.ItemIndicator>
</span>
{children}
</MenubarPrimitive.RadioItem>
));
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
const MenubarLabel = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Label
ref={ref}
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className
)}
{...props}
/>
));
MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
const MenubarSeparator = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
const MenubarShortcut = ({
className,
...props
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className
)}
{...props}
/>
);
};
MenubarShortcut.displayname = "MenubarShortcut";
export {
Menubar,
MenubarMenu,
MenubarTrigger,
MenubarContent,
MenubarItem,
MenubarSeparator,
MenubarLabel,
MenubarCheckboxItem,
MenubarRadioGroup,
MenubarRadioItem,
MenubarPortal,
MenubarSubContent,
MenubarSubTrigger,
MenubarGroup,
MenubarSub,
MenubarShortcut,
};

View file

@ -23,7 +23,9 @@ import {
CodeBracketSquareIcon,
GlobeAltIcon,
PencilSquareIcon,
PlusCircleIcon,
PlusIcon,
PlusSmallIcon,
TrashIcon,
} from "@heroicons/react/24/outline";
import {
@ -54,6 +56,16 @@ import RenameLabel from "../../components/ui/rename-label";
import _ from "lodash";
import { Badge } from "../../components/ui/badge";
import { OpenAiIcon } from "../../icons/OpenAi";
import { Menu } from "@mui/material";
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarRadioGroup,
MenubarRadioItem,
MenubarTrigger,
} from "../../components/ui/menubar";
export default function HomePage() {
const {
@ -88,89 +100,101 @@ export default function HomePage() {
onValueChange={setActiveTab}
className="w-full h-full flex flex-col"
>
<TabsList className="w-full flex justify-between items-center border-b">
<TabsList className="w-full h-16 flex justify-between items-center border-b">
<div className="flex gap-2 justify-start items-center w-96">
<span className="text-2xl ml-4"></span>
<div className="flex gap-2 p-2">
<TabsTrigger value="myflow" className="flex items-center gap-2">
<RenameLabel
value={flows[tabIndex].name}
setValue={(value) => {
if (value !== "") {
let newFlow = _.cloneDeep(flows[tabIndex]);
newFlow.name = value;
updateFlow(newFlow);
}
}}
rename={rename}
setRename={setRename}
/>
<DropdownMenu>
<DropdownMenuTrigger>
<ChevronDownIcon className="w-3" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-40">
<DropdownMenuLabel>Current Flow</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => {
setRename(true);
}}
>
<PencilSquareIcon className="w-4 h-4 mr-2" />
Rename
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
openPopUp(<ImportModal />);
}}
>
<ArrowUpTrayIcon className="w-4 h-4 mr-2" />
Import
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
openPopUp(<ExportModal />);
}}
>
<ArrowDownTrayIcon className="w-4 h-4 mr-2" />
Export
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
openPopUp(<ApiModal flowName={flows[tabIndex].name} />);
}}
>
<CodeBracketSquareIcon className="w-4 h-4 mr-2" />
Code
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>Flows</DropdownMenuLabel>
<DropdownMenuRadioGroup
value={tabIndex.toString()}
onValueChange={(value) => {
setTabIndex(parseInt(value));
}}
>
{flows.map((flow, idx) => {
return (
<DropdownMenuRadioItem value={idx.toString()}>
{flow.name}
</DropdownMenuRadioItem>
);
})}
</DropdownMenuRadioGroup>
<DropdownMenuItem
onClick={() => {
addFlow();
}}
>
<PlusIcon className="w-4 h-4 mr-2" />
Add Flow
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TabsTrigger>
</div>
{activeTab === "myflow" && (
<div className="flex gap-2 p-2">
<Menubar>
<MenubarMenu>
<MenubarTrigger className="px-2">
<b>
<RenameLabel
value={flows[tabIndex].name}
setValue={(value) => {
if (value !== "") {
let newFlow = _.cloneDeep(flows[tabIndex]);
newFlow.name = value;
updateFlow(newFlow);
}
}}
rename={rename}
setRename={setRename}
/>
</b>
</MenubarTrigger>
<MenubarContent>
<MenubarItem
onClick={() => {
openPopUp(<ImportModal />);
}}
>
<ArrowUpTrayIcon className="w-4 h-4 mr-2" />
Import
</MenubarItem>
<MenubarItem
onClick={() => {
openPopUp(<ExportModal />);
}}
>
<ArrowDownTrayIcon className="w-4 h-4 mr-2" />
Export
</MenubarItem>
<MenubarItem
onClick={() => {
openPopUp(
<ApiModal flowName={flows[tabIndex].name} />
);
}}
>
<CodeBracketSquareIcon className="w-4 h-4 mr-2" />
Code
</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Edit</MenubarTrigger>
<MenubarContent>
<MenubarItem
onClick={() => {
setRename(true);
}}
>
<PencilSquareIcon className="w-4 h-4 mr-2" />
Rename
</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Flows</MenubarTrigger>
<MenubarContent>
<MenubarRadioGroup
value={tabIndex.toString()}
onValueChange={(value) => {
setTabIndex(parseInt(value));
}}
>
{flows.map((flow, idx) => {
return (
<MenubarRadioItem value={idx.toString()}>
{flow.name}
</MenubarRadioItem>
);
})}
</MenubarRadioGroup>
<MenubarItem
onClick={() => {
addFlow();
}}
>
<PlusIcon className="w-4 h-4 mr-2" />
Add Flow
</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
</div>
)}
</div>
<div className="flex">
<TabsTrigger value="community">Explore</TabsTrigger>
@ -283,9 +307,13 @@ export default function HomePage() {
<TrashIcon className="w-5 text-primary opacity-0 group-hover:opacity-100 transition-all" />
</button>
</CardTitle>
<CardDescription className="pt-2 pb-8">
{/* {flow.description} */}
{idx === 0 ? "This is a new agent" : "This is a new tool"}
<CardDescription className="pt-2 pb-2">
<div className="truncate-doubleline">
{idx === 0
? "This flow creates an agent that accesses a department store database and APIs to monitor customer activity and overall storage."
: "This is a new tool"}
{/* {flow.description} */}
</div>
</CardDescription>
</CardHeader>
@ -314,7 +342,7 @@ export default function HomePage() {
}}
>
<ArrowTopRightOnSquareIcon className="w-4 mr-2" />
Edit Flow
Edit
</Button>
</div>
</CardFooter>

View file

@ -7,7 +7,6 @@ import {
WrenchScrewdriverIcon,
WrenchIcon,
ComputerDesktopIcon,
Bars3CenterLeftIcon,
GiftIcon,
PaperClipIcon,
QuestionMarkCircleIcon,
@ -15,6 +14,7 @@ import {
ScissorsIcon,
CircleStackIcon,
Squares2X2Icon,
Bars3CenterLeftIcon,
} from "@heroicons/react/24/outline";
import { Connection, Edge, Node, ReactFlowInstance, addEdge } from "reactflow";
import { FlowType, NodeType } from "./types/flow";

View file

@ -111,6 +111,13 @@ module.exports = {
"overflow": "hidden",
"text-overflow": "ellipsis",
},
".truncate-doubleline": {
"display": "-webkit-box",
"-webkit-line-clamp": "2", /* Change this number to the number of lines you want to show */
"-webkit-box-orient": "vertical",
"overflow": "hidden",
"text-overflow": "ellipsis",
},
".arrow-hide": {
"&::-webkit-inner-spin-button": {