Back button added, chevron with dropdown added to flow name
This commit is contained in:
parent
e491064662
commit
2d640c8e5a
5 changed files with 209 additions and 214 deletions
BIN
langflow.db
BIN
langflow.db
Binary file not shown.
|
|
@ -1,18 +1,26 @@
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||||
import { PopUpContext } from "../../../../contexts/popUpContext";
|
import { PopUpContext } from "../../../../contexts/popUpContext";
|
||||||
import { Save, Edit, Upload, Download, Code, Plus } from "lucide-react";
|
|
||||||
import {
|
import {
|
||||||
Menubar,
|
Save,
|
||||||
MenubarContent,
|
Edit,
|
||||||
MenubarItem,
|
Upload,
|
||||||
MenubarMenu,
|
Download,
|
||||||
MenubarTrigger,
|
Code,
|
||||||
MenubarRadioGroup,
|
Plus,
|
||||||
MenubarRadioItem,
|
ChevronDown,
|
||||||
MenubarLabel,
|
ChevronLeft,
|
||||||
MenubarSeparator,
|
} from "lucide-react";
|
||||||
} from "../../../ui/menubar";
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
DropdownMenuRadioGroup,
|
||||||
|
DropdownMenuRadioItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
} from "../../../ui/dropdown-menu";
|
||||||
|
|
||||||
import RenameLabel from "../../../ui/rename-label";
|
import RenameLabel from "../../../ui/rename-label";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
|
@ -23,7 +31,7 @@ import { alertContext } from "../../../../contexts/alertContext";
|
||||||
import { updateFlowInDatabase } from "../../../../controllers/API";
|
import { updateFlowInDatabase } from "../../../../controllers/API";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export const MenuBar = ({ activeTab, setRename, rename, flows, tabId }) => {
|
export const MenuBar = ({ setRename, rename, flows, tabId }) => {
|
||||||
const { updateFlow, setTabId, addFlow } = useContext(TabsContext);
|
const { updateFlow, setTabId, addFlow } = useContext(TabsContext);
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
const { openPopUp } = useContext(PopUpContext);
|
const { openPopUp } = useContext(PopUpContext);
|
||||||
|
|
@ -47,109 +55,102 @@ export const MenuBar = ({ activeTab, setRename, rename, flows, tabId }) => {
|
||||||
}
|
}
|
||||||
let current_flow = flows.find((flow) => flow.id === tabId);
|
let current_flow = flows.find((flow) => flow.id === tabId);
|
||||||
|
|
||||||
// robot emoji
|
|
||||||
let emoji = current_flow.style?.emoji || "🤖";
|
|
||||||
let color = current_flow.style?.color || "bg-blue-200";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menubar>
|
<div className="flex gap-2 items-center">
|
||||||
<MenubarMenu>
|
<Link to="/">
|
||||||
<MenubarTrigger className="px-1">
|
<ChevronLeft className="w-5" />
|
||||||
<RenameLabel
|
</Link>
|
||||||
value={current_flow.name}
|
<div className="flex items-center font-medium text-sm rounded-md py-1 px-1.5 bg-background gap-0.5">
|
||||||
setValue={(value) => {
|
<RenameLabel
|
||||||
if (value !== "") {
|
value={current_flow.name}
|
||||||
let newFlow = _.cloneDeep(current_flow);
|
setValue={(value) => {
|
||||||
newFlow.name = value;
|
if (value !== "") {
|
||||||
updateFlow(newFlow);
|
let newFlow = _.cloneDeep(current_flow);
|
||||||
}
|
newFlow.name = value;
|
||||||
|
updateFlow(newFlow);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
rename={rename}
|
||||||
|
setRename={setRename}
|
||||||
|
/>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger className="px-1">
|
||||||
|
<ChevronDown className="w-4 h-4" />
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="w-44">
|
||||||
|
<DropdownMenuLabel>File</DropdownMenuLabel>
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => {
|
||||||
|
openPopUp(<ImportModal />);
|
||||||
}}
|
}}
|
||||||
rename={rename}
|
>
|
||||||
setRename={setRename}
|
<Upload className="w-4 h-4 mr-2" />
|
||||||
/>
|
Import
|
||||||
|
</DropdownMenuItem>
|
||||||
</MenubarTrigger>
|
<DropdownMenuItem
|
||||||
<MenubarContent>
|
onClick={() => {
|
||||||
<MenubarLabel>
|
openPopUp(<ExportModal />);
|
||||||
File
|
}}
|
||||||
</MenubarLabel>
|
>
|
||||||
<MenubarItem
|
<Download className="w-4 h-4 mr-2" />
|
||||||
onClick={() => {
|
Export
|
||||||
openPopUp(<ImportModal />);
|
</DropdownMenuItem>
|
||||||
}}
|
<DropdownMenuItem
|
||||||
>
|
onClick={() => {
|
||||||
<Upload className="w-4 h-4 mr-2" />
|
openPopUp(<ApiModal flow={current_flow} />);
|
||||||
Import
|
}}
|
||||||
</MenubarItem>
|
>
|
||||||
<MenubarItem
|
<Code className="w-4 h-4 mr-2" />
|
||||||
onClick={() => {
|
Code
|
||||||
openPopUp(<ExportModal />);
|
</DropdownMenuItem>
|
||||||
}}
|
<DropdownMenuSeparator />
|
||||||
>
|
<DropdownMenuLabel>Edit</DropdownMenuLabel>
|
||||||
<Download className="w-4 h-4 mr-2" />
|
<DropdownMenuItem
|
||||||
Export
|
onClick={() => {
|
||||||
</MenubarItem>
|
handleSaveFlow(current_flow);
|
||||||
<MenubarItem
|
}}
|
||||||
onClick={() => {
|
>
|
||||||
openPopUp(<ApiModal flow={current_flow} />);
|
<Save className="w-4 h-4 mr-2" />
|
||||||
}}
|
Save
|
||||||
>
|
</DropdownMenuItem>
|
||||||
<Code className="w-4 h-4 mr-2" />
|
<DropdownMenuItem
|
||||||
Code
|
onClick={() => {
|
||||||
</MenubarItem>
|
setRename(true);
|
||||||
<MenubarSeparator />
|
}}
|
||||||
<MenubarLabel>
|
>
|
||||||
Edit
|
<Edit className="w-4 h-4 mr-2" />
|
||||||
</MenubarLabel>
|
Rename
|
||||||
<MenubarItem
|
</DropdownMenuItem>
|
||||||
onClick={() => {
|
<DropdownMenuSeparator />
|
||||||
handleSaveFlow(current_flow);
|
<DropdownMenuLabel>Flows</DropdownMenuLabel>
|
||||||
}}
|
<DropdownMenuRadioGroup
|
||||||
>
|
value={tabId}
|
||||||
<Save className="w-4 h-4 mr-2" />
|
onValueChange={(value) => {
|
||||||
Save
|
setTabId(value);
|
||||||
</MenubarItem>
|
}}
|
||||||
<MenubarItem
|
>
|
||||||
onClick={() => {
|
{flows.map((flow, idx) => {
|
||||||
setRename(true);
|
return (
|
||||||
}}
|
<Link to={"/flow/" + flow.id}>
|
||||||
>
|
<DropdownMenuRadioItem value={flow.id}>
|
||||||
<Edit className="w-4 h-4 mr-2" />
|
{flow.name}
|
||||||
Rename
|
</DropdownMenuRadioItem>
|
||||||
</MenubarItem>
|
</Link>
|
||||||
<MenubarSeparator />
|
);
|
||||||
<MenubarLabel>
|
})}
|
||||||
Flows
|
</DropdownMenuRadioGroup>
|
||||||
</MenubarLabel>
|
<DropdownMenuItem
|
||||||
<MenubarRadioGroup
|
onClick={() => {
|
||||||
value={tabId}
|
handleAddFlow();
|
||||||
onValueChange={(value) => {
|
}}
|
||||||
setTabId(value);
|
>
|
||||||
}}
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
>
|
Add Flow
|
||||||
{flows.map((flow, idx) => {
|
</DropdownMenuItem>
|
||||||
return (
|
</DropdownMenuContent>
|
||||||
<Link to={"/flow/" + flow.id}>
|
</DropdownMenu>
|
||||||
<MenubarRadioItem value={flow.id}>
|
</div>
|
||||||
{emoji} {flow.name}
|
</div>
|
||||||
</MenubarRadioItem>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</MenubarRadioGroup>
|
|
||||||
<MenubarItem
|
|
||||||
onClick={() => {
|
|
||||||
handleAddFlow();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Plus className="w-4 h-4 mr-2" />
|
|
||||||
Add Flow
|
|
||||||
</MenubarItem>
|
|
||||||
</MenubarContent>
|
|
||||||
</MenubarMenu>
|
|
||||||
|
|
||||||
</Menubar>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { SunIcon, MoonIcon, BellIcon} from "lucide-react";
|
import { SunIcon, MoonIcon, BellIcon } from "lucide-react";
|
||||||
import { useContext, useState, useEffect } from "react";
|
import { useContext, useState, useEffect } from "react";
|
||||||
import { FaGithub } from "react-icons/fa";
|
import { FaGithub } from "react-icons/fa";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
|
|
@ -9,110 +9,101 @@ import { darkContext } from "../../contexts/darkContext";
|
||||||
import { PopUpContext } from "../../contexts/popUpContext";
|
import { PopUpContext } from "../../contexts/popUpContext";
|
||||||
import { typesContext } from "../../contexts/typesContext";
|
import { typesContext } from "../../contexts/typesContext";
|
||||||
import MenuBar from "./components/menuBar";
|
import MenuBar from "./components/menuBar";
|
||||||
import { Link } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
|
|
||||||
export default function Header(){
|
export default function Header() {
|
||||||
const {
|
const { flows, addFlow, tabId } = useContext(TabsContext);
|
||||||
flows,
|
const { openPopUp } = useContext(PopUpContext);
|
||||||
addFlow,
|
const { templates } = useContext(typesContext);
|
||||||
removeFlow,
|
const { id } = useParams();
|
||||||
tabId,
|
const AlertWidth = 384;
|
||||||
setTabId,
|
const { dark, setDark } = useContext(darkContext);
|
||||||
uploadFlow,
|
const [rename, setRename] = useState(false);
|
||||||
downloadFlow,
|
const { notificationCenter, setNotificationCenter, setErrorData } =
|
||||||
} = useContext(TabsContext);
|
useContext(alertContext);
|
||||||
const { openPopUp } = useContext(PopUpContext);
|
useEffect(() => {
|
||||||
const { templates } = useContext(typesContext);
|
//create the first flow
|
||||||
const AlertWidth = 384;
|
if (flows.length === 0 && Object.keys(templates).length > 0) {
|
||||||
const { dark, setDark } = useContext(darkContext);
|
addFlow();
|
||||||
const [activeTab, setActiveTab] = useState("myflow");
|
}
|
||||||
const [rename, setRename] = useState(false);
|
}, [addFlow, flows.length, templates]);
|
||||||
const { notificationCenter, setNotificationCenter, setErrorData } =
|
return (
|
||||||
useContext(alertContext);
|
<div className="w-full h-12 flex justify-between items-center border-b bg-muted">
|
||||||
useEffect(() => {
|
<div className="flex gap-2 justify-start items-center w-96">
|
||||||
//create the first flow
|
<Link to="/">
|
||||||
if (flows.length === 0 && Object.keys(templates).length > 0) {
|
<span className="text-2xl ml-4">⛓️</span>
|
||||||
addFlow();
|
</Link>
|
||||||
}
|
{flows.findIndex((f) => tabId === f.id) !== -1 && tabId !== "" && (
|
||||||
}, [addFlow, flows.length, templates]);
|
|
||||||
return (
|
|
||||||
<div className="w-full h-14 flex justify-between items-center border-b bg-muted">
|
|
||||||
|
|
||||||
<div className="flex gap-2 justify-start items-center w-96">
|
|
||||||
<Link to="/"><span className="text-2xl ml-4">⛓️</span></Link>
|
|
||||||
{flows.findIndex((f) => tabId === f.id) !== -1 &&
|
|
||||||
<MenuBar
|
<MenuBar
|
||||||
activeTab={activeTab}
|
|
||||||
setRename={setRename}
|
setRename={setRename}
|
||||||
rename={rename}
|
rename={rename}
|
||||||
flows={flows}
|
flows={flows}
|
||||||
tabId={tabId}
|
tabId={tabId}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
<div className="flex justify-end px-2 w-96">
|
||||||
<div className="flex justify-end px-2 w-96">
|
<div className="ml-auto mr-2 flex gap-5">
|
||||||
<div className="ml-auto mr-2 flex gap-5">
|
<Button
|
||||||
<Button
|
asChild
|
||||||
asChild
|
variant="outline"
|
||||||
variant="outline"
|
className="text-gray-600 dark:text-gray-300 "
|
||||||
className="text-gray-600 dark:text-gray-300 "
|
>
|
||||||
>
|
<a
|
||||||
<a
|
href="https://github.com/logspace-ai/langflow"
|
||||||
href="https://github.com/logspace-ai/langflow"
|
target="_blank"
|
||||||
target="_blank"
|
rel="noreferrer"
|
||||||
rel="noreferrer"
|
className="flex"
|
||||||
className="flex"
|
>
|
||||||
>
|
<FaGithub className="h-5 w-5 mr-2" />
|
||||||
<FaGithub className="h-5 w-5 mr-2" />
|
Join The Community
|
||||||
Join The Community
|
</a>
|
||||||
</a>
|
</Button>
|
||||||
</Button>
|
<button
|
||||||
<button
|
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
|
||||||
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
|
onClick={() => {
|
||||||
onClick={() => {
|
setDark(!dark);
|
||||||
setDark(!dark);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{dark ? (
|
||||||
{dark ? (
|
<SunIcon className="h-5 w-5" />
|
||||||
<SunIcon className="h-5 w-5" />
|
) : (
|
||||||
) : (
|
<MoonIcon className="h-5 w-5" />
|
||||||
<MoonIcon className="h-5 w-5" />
|
)}
|
||||||
)}
|
</button>
|
||||||
</button>
|
<button
|
||||||
<button
|
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200 relative"
|
||||||
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200 relative"
|
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
||||||
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
setNotificationCenter(false);
|
||||||
setNotificationCenter(false);
|
const { top, left } = (
|
||||||
const { top, left } = (
|
event.target as Element
|
||||||
event.target as Element
|
).getBoundingClientRect();
|
||||||
).getBoundingClientRect();
|
openPopUp(
|
||||||
openPopUp(
|
<>
|
||||||
<>
|
<div
|
||||||
<div
|
className="z-10 absolute"
|
||||||
className="z-10 absolute"
|
style={{ top: top + 34, left: left - AlertWidth }}
|
||||||
style={{ top: top + 34, left: left - AlertWidth }}
|
>
|
||||||
>
|
<AlertDropdown />
|
||||||
<AlertDropdown />
|
</div>
|
||||||
</div>
|
<div className="h-screen w-screen fixed top-0 left-0"></div>
|
||||||
<div className="h-screen w-screen fixed top-0 left-0"></div>
|
</>
|
||||||
</>
|
);
|
||||||
);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{notificationCenter && (
|
||||||
{notificationCenter && (
|
<div className="absolute w-1.5 h-1.5 rounded-full bg-destructive right-[3px]"></div>
|
||||||
<div className="absolute w-1.5 h-1.5 rounded-full bg-destructive right-[3px]"></div>
|
)}
|
||||||
)}
|
<BellIcon className="h-5 w-5" aria-hidden="true" />
|
||||||
<BellIcon className="h-5 w-5" aria-hidden="true" />
|
</button>
|
||||||
</button>
|
<button>
|
||||||
<button>
|
<img
|
||||||
<img
|
src="https://github.com/shadcn.png"
|
||||||
src="https://github.com/shadcn.png"
|
className="rounded-full w-8"
|
||||||
className="rounded-full w-8"
|
/>
|
||||||
/>
|
</button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
</div>
|
||||||
}
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
||||||
<div className="flex grow shrink basis-auto min-h-0 flex-1 overflow-hidden">
|
<div className="flex grow shrink basis-auto min-h-0 flex-1 overflow-hidden">
|
||||||
<ExtraSidebar />
|
<ExtraSidebar />
|
||||||
{/* Main area */}
|
{/* Main area */}
|
||||||
<main className="min-w-0 flex-1 border-t border-gray-200 dark:border-gray-700 flex">
|
<main className="flex-1 flex">
|
||||||
{/* Primary column */}
|
{/* Primary column */}
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full">
|
||||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ export default function HomePage() {
|
||||||
removeFlow,
|
removeFlow,
|
||||||
setTabId,
|
setTabId,
|
||||||
} = useContext(TabsContext);
|
} = useContext(TabsContext);
|
||||||
|
useEffect(() => {
|
||||||
|
setTabId("");
|
||||||
|
}, [])
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full h-full flex flex-col bg-muted"
|
className="w-full h-full flex flex-col bg-muted"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue