fix: refactor settings page to use new sidebar and fix old bugs (#4545)
* Updated settings page sidebar to new sidebar * Updated old home page to still work * Fix padding on collapsed sidebar * Fix able to drag on input component * Fixed pagination position on big screens --------- Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com>
This commit is contained in:
parent
9c004e7646
commit
e68c21a7af
16 changed files with 272 additions and 225 deletions
File diff suppressed because one or more lines are too long
|
|
@ -683,7 +683,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from crewai import Crew, Process\n\nfrom langflow.base.agents.crewai.crew import BaseCrewComponent\nfrom langflow.io import HandleInput\n\n\nclass HierarchicalCrewComponent(BaseCrewComponent):\n display_name: str = \"Hierarchical Crew\"\n description: str = (\n \"Represents a group of agents, defining how they should collaborate and the tasks they should perform.\"\n )\n documentation: str = \"https://docs.crewai.com/how-to/Hierarchical/\"\n icon = \"CrewAI\"\n\n inputs = [\n *BaseCrewComponent._base_inputs,\n HandleInput(name=\"agents\", display_name=\"Agents\", input_types=[\"Agent\"], is_list=True),\n HandleInput(name=\"tasks\", display_name=\"Tasks\", input_types=[\"HierarchicalTask\"], is_list=True),\n HandleInput(name=\"manager_llm\", display_name=\"Manager LLM\", input_types=[\"LanguageModel\"], required=False),\n HandleInput(name=\"manager_agent\", display_name=\"Manager Agent\", input_types=[\"Agent\"], required=False),\n ]\n\n def build_crew(self) -> Crew:\n tasks, agents = self.get_tasks_and_agents()\n return Crew(\n agents=agents,\n tasks=tasks,\n process=Process.hierarchical,\n verbose=self.verbose,\n memory=self.memory,\n cache=self.use_cache,\n max_rpm=self.max_rpm,\n share_crew=self.share_crew,\n function_calling_llm=self.function_calling_llm,\n manager_agent=self.manager_agent,\n manager_llm=self.manager_llm,\n step_callback=self.get_step_callback(),\n task_callback=self.get_task_callback(),\n )\n"
|
||||
"value": "import os\n\nfrom crewai import Crew, Process\n\nfrom langflow.base.agents.crewai.crew import BaseCrewComponent\nfrom langflow.io import HandleInput, SecretStrInput\n\n\nclass HierarchicalCrewComponent(BaseCrewComponent):\n display_name: str = \"Hierarchical Crew\"\n description: str = (\n \"Represents a group of agents, defining how they should collaborate and the tasks they should perform.\"\n )\n documentation: str = \"https://docs.crewai.com/how-to/Hierarchical/\"\n icon = \"CrewAI\"\n\n inputs = [\n *BaseCrewComponent._base_inputs,\n HandleInput(name=\"agents\", display_name=\"Agents\", input_types=[\"Agent\"], is_list=True),\n HandleInput(name=\"tasks\", display_name=\"Tasks\", input_types=[\"HierarchicalTask\"], is_list=True),\n HandleInput(name=\"manager_llm\", display_name=\"Manager LLM\", input_types=[\"LanguageModel\"], required=False),\n HandleInput(name=\"manager_agent\", display_name=\"Manager Agent\", input_types=[\"Agent\"], required=False),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n value=\"OPENAI_API_KEY\",\n ),\n ]\n\n def build_crew(self) -> Crew:\n tasks, agents = self.get_tasks_and_agents()\n\n # Set the OpenAI API Key\n if self.openai_api_key:\n os.environ[\"OPENAI_API_KEY\"] = self.openai_api_key\n\n return Crew(\n agents=agents,\n tasks=tasks,\n process=Process.hierarchical,\n verbose=self.verbose,\n memory=self.memory,\n cache=self.use_cache,\n max_rpm=self.max_rpm,\n share_crew=self.share_crew,\n function_calling_llm=self.function_calling_llm,\n manager_agent=self.manager_agent,\n manager_llm=self.manager_llm,\n step_callback=self.get_step_callback(),\n task_callback=self.get_task_callback(),\n )\n"
|
||||
},
|
||||
"function_calling_llm": {
|
||||
"advanced": true,
|
||||
|
|
@ -769,6 +769,25 @@
|
|||
"type": "bool",
|
||||
"value": false
|
||||
},
|
||||
"openai_api_key": {
|
||||
"_input_type": "SecretStrInput",
|
||||
"advanced": false,
|
||||
"display_name": "OpenAI API Key",
|
||||
"dynamic": false,
|
||||
"info": "The OpenAI API Key to use for the OpenAI model.",
|
||||
"input_types": [
|
||||
"Message"
|
||||
],
|
||||
"load_from_db": true,
|
||||
"name": "openai_api_key",
|
||||
"password": true,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "OPENAI_API_KEY"
|
||||
},
|
||||
"share_crew": {
|
||||
"advanced": true,
|
||||
"display_name": "Share Crew",
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from crewai import Crew, Process\n\nfrom langflow.base.agents.crewai.crew import BaseCrewComponent\nfrom langflow.io import HandleInput\n\n\nclass HierarchicalCrewComponent(BaseCrewComponent):\n display_name: str = \"Hierarchical Crew\"\n description: str = (\n \"Represents a group of agents, defining how they should collaborate and the tasks they should perform.\"\n )\n documentation: str = \"https://docs.crewai.com/how-to/Hierarchical/\"\n icon = \"CrewAI\"\n\n inputs = [\n *BaseCrewComponent._base_inputs,\n HandleInput(name=\"agents\", display_name=\"Agents\", input_types=[\"Agent\"], is_list=True),\n HandleInput(name=\"tasks\", display_name=\"Tasks\", input_types=[\"HierarchicalTask\"], is_list=True),\n HandleInput(name=\"manager_llm\", display_name=\"Manager LLM\", input_types=[\"LanguageModel\"], required=False),\n HandleInput(name=\"manager_agent\", display_name=\"Manager Agent\", input_types=[\"Agent\"], required=False),\n ]\n\n def build_crew(self) -> Crew:\n tasks, agents = self.get_tasks_and_agents()\n return Crew(\n agents=agents,\n tasks=tasks,\n process=Process.hierarchical,\n verbose=self.verbose,\n memory=self.memory,\n cache=self.use_cache,\n max_rpm=self.max_rpm,\n share_crew=self.share_crew,\n function_calling_llm=self.function_calling_llm,\n manager_agent=self.manager_agent,\n manager_llm=self.manager_llm,\n step_callback=self.get_step_callback(),\n task_callback=self.get_task_callback(),\n )\n"
|
||||
"value": "import os\n\nfrom crewai import Crew, Process\n\nfrom langflow.base.agents.crewai.crew import BaseCrewComponent\nfrom langflow.io import HandleInput, SecretStrInput\n\n\nclass HierarchicalCrewComponent(BaseCrewComponent):\n display_name: str = \"Hierarchical Crew\"\n description: str = (\n \"Represents a group of agents, defining how they should collaborate and the tasks they should perform.\"\n )\n documentation: str = \"https://docs.crewai.com/how-to/Hierarchical/\"\n icon = \"CrewAI\"\n\n inputs = [\n *BaseCrewComponent._base_inputs,\n HandleInput(name=\"agents\", display_name=\"Agents\", input_types=[\"Agent\"], is_list=True),\n HandleInput(name=\"tasks\", display_name=\"Tasks\", input_types=[\"HierarchicalTask\"], is_list=True),\n HandleInput(name=\"manager_llm\", display_name=\"Manager LLM\", input_types=[\"LanguageModel\"], required=False),\n HandleInput(name=\"manager_agent\", display_name=\"Manager Agent\", input_types=[\"Agent\"], required=False),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n value=\"OPENAI_API_KEY\",\n ),\n ]\n\n def build_crew(self) -> Crew:\n tasks, agents = self.get_tasks_and_agents()\n\n # Set the OpenAI API Key\n if self.openai_api_key:\n os.environ[\"OPENAI_API_KEY\"] = self.openai_api_key\n\n return Crew(\n agents=agents,\n tasks=tasks,\n process=Process.hierarchical,\n verbose=self.verbose,\n memory=self.memory,\n cache=self.use_cache,\n max_rpm=self.max_rpm,\n share_crew=self.share_crew,\n function_calling_llm=self.function_calling_llm,\n manager_agent=self.manager_agent,\n manager_llm=self.manager_llm,\n step_callback=self.get_step_callback(),\n task_callback=self.get_task_callback(),\n )\n"
|
||||
},
|
||||
"function_calling_llm": {
|
||||
"advanced": true,
|
||||
|
|
@ -466,6 +466,25 @@
|
|||
"type": "bool",
|
||||
"value": false
|
||||
},
|
||||
"openai_api_key": {
|
||||
"_input_type": "SecretStrInput",
|
||||
"advanced": false,
|
||||
"display_name": "OpenAI API Key",
|
||||
"dynamic": false,
|
||||
"info": "The OpenAI API Key to use for the OpenAI model.",
|
||||
"input_types": [
|
||||
"Message"
|
||||
],
|
||||
"load_from_db": true,
|
||||
"name": "openai_api_key",
|
||||
"password": true,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "OPENAI_API_KEY"
|
||||
},
|
||||
"share_crew": {
|
||||
"advanced": true,
|
||||
"display_name": "Share Crew",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
1
src/frontend/package-lock.json
generated
1
src/frontend/package-lock.json
generated
|
|
@ -835,7 +835,6 @@
|
|||
},
|
||||
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
|
||||
"version": "1.3.0",
|
||||
"extraneous": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -70,8 +70,6 @@ const SideBarFoldersButtonsComponent = ({
|
|||
const urlWithoutPath =
|
||||
pathname.split("/").length < (ENABLE_CUSTOM_PARAM ? 5 : 4);
|
||||
const myCollectionId = useFolderStore((state) => state.myCollectionId);
|
||||
const folderIdDragging = useFolderStore((state) => state.folderIdDragging);
|
||||
|
||||
const checkPathName = (itemId: string) => {
|
||||
if (urlWithoutPath && itemId === myCollectionId) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { useFolderStore } from "@/stores/foldersStore";
|
||||
import { useIsFetching } from "@tanstack/react-query";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { FolderType } from "../../pages/MainPage/entities";
|
||||
import SideBarFoldersButtonsComponent from "./components/sideBarFolderButtons";
|
||||
|
|
@ -17,13 +15,6 @@ export default function FolderSidebarNav({
|
|||
...props
|
||||
}: SidebarNavProps) {
|
||||
const location = useLocation();
|
||||
const pathname = location.pathname;
|
||||
const folders = useFolderStore((state) => state.folders);
|
||||
|
||||
const isPending = !!useIsFetching({
|
||||
queryKey: ["useGetFolders"],
|
||||
exact: false,
|
||||
});
|
||||
|
||||
return (
|
||||
<SideBarFoldersButtonsComponent
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ const CustomInputPopover = ({
|
|||
<div
|
||||
data-testid={`anchor-${id}`}
|
||||
className={cn(
|
||||
"primary-input border-1 flex h-full min-h-[2.375rem] flex-wrap items-center px-3",
|
||||
"primary-input noflow nowheel nopan nodelete nodrag border-1 flex h-full min-h-[2.375rem] cursor-default flex-wrap items-center px-3",
|
||||
editNode && "min-h-7 p-0",
|
||||
editNode && disabled && "min-h-5 border-muted p-0",
|
||||
disabled && "bg-muted text-muted",
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ export default function PageLayout({
|
|||
const navigate = useCustomNavigate();
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-1 flex-col justify-between overflow-auto bg-background px-6 pt-10">
|
||||
<div className="flex w-full flex-1 flex-col justify-between overflow-auto overflow-x-hidden bg-background">
|
||||
<div className="mx-auto flex w-full max-w-[1440px] flex-1 flex-col">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-4 p-6 pt-10">
|
||||
<CustomBanner />
|
||||
<div className="flex w-full items-center justify-between gap-4 space-y-0.5 py-2">
|
||||
<div className="flex w-full flex-col">
|
||||
|
|
@ -55,8 +55,10 @@ export default function PageLayout({
|
|||
<div className="flex-shrink-0">{button && button}</div>
|
||||
</div>
|
||||
</div>
|
||||
<Separator className="my-6 flex" />
|
||||
{children}
|
||||
<div className="flex shrink-0 px-6">
|
||||
<Separator className="flex" />
|
||||
</div>
|
||||
<div className="flex flex-1 p-6 pt-7">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
import { CustomLink } from "@/customization/components/custom-link";
|
||||
import { cn } from "../../../../utils/utils";
|
||||
import { buttonVariants } from "../../../ui/button";
|
||||
|
||||
type SideBarButtonsComponentProps = {
|
||||
items: {
|
||||
href?: string;
|
||||
title: string;
|
||||
icon: React.ReactNode;
|
||||
}[];
|
||||
pathname: string;
|
||||
handleOpenNewFolderModal?: () => void;
|
||||
};
|
||||
const SideBarButtonsComponent = ({
|
||||
items,
|
||||
pathname,
|
||||
}: SideBarButtonsComponentProps) => {
|
||||
return (
|
||||
<div className="flex gap-2 overflow-auto lg:h-[70vh] lg:flex-col">
|
||||
{items.map((item, index) => (
|
||||
<CustomLink key={index} to={item.href!}>
|
||||
<div
|
||||
key={item.title}
|
||||
data-testid={`sidebar-nav-${item.title}`}
|
||||
className={cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
item.href && pathname.endsWith(item.href)
|
||||
? "border border-border bg-muted hover:bg-muted"
|
||||
: "border border-transparent hover:border-border hover:bg-transparent",
|
||||
"flex w-full shrink-0 justify-start gap-4",
|
||||
)}
|
||||
>
|
||||
{item.icon}
|
||||
<span className="block max-w-full truncate opacity-100">
|
||||
{item.title}
|
||||
</span>
|
||||
</div>
|
||||
</CustomLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default SideBarButtonsComponent;
|
||||
|
|
@ -1,30 +1,62 @@
|
|||
import { CustomLink } from "@/customization/components/custom-link";
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { cn } from "../../utils/utils";
|
||||
import HorizontalScrollFadeComponent from "../horizontalScrollFadeComponent";
|
||||
import SideBarButtonsComponent from "./components/sideBarButtons";
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../ui/sidebar";
|
||||
|
||||
type SidebarNavProps = {
|
||||
type SideBarButtonsComponentProps = {
|
||||
items: {
|
||||
href?: string;
|
||||
title: string;
|
||||
icon: React.ReactNode;
|
||||
}[];
|
||||
className?: string;
|
||||
handleOpenNewFolderModal?: () => void;
|
||||
};
|
||||
|
||||
export default function SidebarNav({
|
||||
className,
|
||||
items,
|
||||
...props
|
||||
}: SidebarNavProps) {
|
||||
const SideBarButtonsComponent = ({ items }: SideBarButtonsComponentProps) => {
|
||||
const location = useLocation();
|
||||
const pathname = location.pathname;
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<nav className={cn(className)} {...props}>
|
||||
<HorizontalScrollFadeComponent>
|
||||
<SideBarButtonsComponent items={items} pathname={pathname} />
|
||||
</HorizontalScrollFadeComponent>
|
||||
</nav>
|
||||
<Sidebar collapsible={isMobile ? "icon" : "none"} className="border-none">
|
||||
<SidebarContent className="pr-6">
|
||||
<SidebarGroup>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{items.map((item, index) => (
|
||||
<SidebarMenuItem key={index}>
|
||||
<CustomLink to={item.href!}>
|
||||
<SidebarMenuButton
|
||||
size="md"
|
||||
isActive={
|
||||
item.href ? pathname.endsWith(item.href) : false
|
||||
}
|
||||
data-testid={`sidebar-nav-${item.title}`}
|
||||
tooltip={item.title}
|
||||
>
|
||||
{item.icon}
|
||||
<span className="block max-w-full truncate">
|
||||
{item.title}
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</CustomLink>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</SidebarContent>
|
||||
</Sidebar>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default SideBarButtonsComponent;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ type SidebarContext = {
|
|||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
toggleSidebar: () => void;
|
||||
defaultOpen: boolean;
|
||||
};
|
||||
|
||||
const SidebarContext = React.createContext<SidebarContext | null>(null);
|
||||
|
|
@ -114,8 +115,9 @@ const SidebarProvider = React.forwardRef<
|
|||
open,
|
||||
setOpen,
|
||||
toggleSidebar,
|
||||
defaultOpen,
|
||||
}),
|
||||
[state, open, setOpen, toggleSidebar],
|
||||
[state, open, setOpen, toggleSidebar, defaultOpen],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
@ -164,29 +166,30 @@ const Sidebar = React.forwardRef<
|
|||
},
|
||||
ref,
|
||||
) => {
|
||||
const { state, setOpen } = useSidebar();
|
||||
const { state, setOpen, defaultOpen } = useSidebar();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (collapsible === "none") {
|
||||
console.log("collapsible === none");
|
||||
setOpen(true);
|
||||
} else {
|
||||
setOpen(defaultOpen);
|
||||
}
|
||||
}, [collapsible]);
|
||||
|
||||
if (collapsible === "none") {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"group flex h-full w-[--sidebar-width] flex-col bg-background text-foreground",
|
||||
className,
|
||||
)}
|
||||
className={cn("group flex h-full flex-col")}
|
||||
data-side={side}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
data-sidebar="sidebar"
|
||||
className="flex h-full w-full flex-col group-data-[side=left]:border-r group-data-[side=right]:border-l"
|
||||
className={cn(
|
||||
"group flex h-full w-[--sidebar-width] flex-col bg-background text-foreground group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import FolderSidebarNav from "@/components/folderSidebarComponent";
|
||||
import { SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { useDeleteFolders } from "@/controllers/API/queries/folders";
|
||||
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
|
||||
import { track } from "@/customization/utils/analytics";
|
||||
|
|
@ -80,41 +81,43 @@ export default function OldHomePage(): JSX.Element {
|
|||
return (
|
||||
<>
|
||||
<div className="flex h-full w-full space-y-8 md:flex-col lg:flex-row lg:space-y-0">
|
||||
<aside className="hidden h-full w-fit flex-col space-y-6 border-r px-4 lg:flex">
|
||||
<FolderSidebarNav
|
||||
handleChangeFolder={(id: string) => {
|
||||
navigate(`all/folder/${id}`);
|
||||
}}
|
||||
handleDeleteFolder={(item) => {
|
||||
setFolderToEdit(item);
|
||||
setOpenDeleteFolderModal(true);
|
||||
}}
|
||||
className="w-[20vw] max-w-[288px]"
|
||||
/>
|
||||
</aside>
|
||||
<PageLayout
|
||||
title={USER_PROJECTS_HEADER}
|
||||
description={MY_COLLECTION_DESC}
|
||||
button={
|
||||
<div className="flex gap-2">
|
||||
<DropdownButton
|
||||
firstButtonName="New Project"
|
||||
onFirstBtnClick={() => {
|
||||
setOpenModal(true);
|
||||
track("New Project Button Clicked");
|
||||
}}
|
||||
options={dropdownOptions}
|
||||
plusButton={true}
|
||||
dropdownOptions={false}
|
||||
isFetchingFolders={isLoadingFolder}
|
||||
/>
|
||||
<SidebarProvider>
|
||||
<aside className="hidden h-full w-fit flex-col space-y-6 px-4 lg:flex">
|
||||
<FolderSidebarNav
|
||||
handleChangeFolder={(id: string) => {
|
||||
navigate(`all/folder/${id}`);
|
||||
}}
|
||||
handleDeleteFolder={(item) => {
|
||||
setFolderToEdit(item);
|
||||
setOpenDeleteFolderModal(true);
|
||||
}}
|
||||
className="w-[20vw] max-w-[288px]"
|
||||
/>
|
||||
</aside>
|
||||
<PageLayout
|
||||
title={USER_PROJECTS_HEADER}
|
||||
description={MY_COLLECTION_DESC}
|
||||
button={
|
||||
<div className="flex gap-2">
|
||||
<DropdownButton
|
||||
firstButtonName="New Project"
|
||||
onFirstBtnClick={() => {
|
||||
setOpenModal(true);
|
||||
track("New Project Button Clicked");
|
||||
}}
|
||||
options={dropdownOptions}
|
||||
plusButton={true}
|
||||
dropdownOptions={false}
|
||||
isFetchingFolders={isLoadingFolder}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="relative h-full w-full flex-1">
|
||||
<Outlet />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="relative h-full w-full flex-1">
|
||||
<Outlet />
|
||||
</div>
|
||||
</PageLayout>
|
||||
</PageLayout>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
<ModalsComponent
|
||||
openModal={openModal}
|
||||
|
|
|
|||
|
|
@ -86,94 +86,116 @@ const HomePage = ({ type }) => {
|
|||
className="flex h-full w-full flex-col overflow-y-auto"
|
||||
data-testid="cards-wrapper"
|
||||
>
|
||||
{ENABLE_DATASTAX_LANGFLOW && <CustomBanner />}
|
||||
|
||||
{/* mt-10 to mt-8 for Datastax LF */}
|
||||
<div className="flex flex-1 flex-col justify-start px-5 pt-10">
|
||||
<div className="flex flex-col justify-start xl:container">
|
||||
<HeaderComponent
|
||||
folderName={folderName}
|
||||
flowType={flowType}
|
||||
setFlowType={setFlowType}
|
||||
view={view}
|
||||
setView={setView}
|
||||
setNewProjectModal={setNewProjectModal}
|
||||
setSearch={onSearch}
|
||||
isEmptyFolder={isEmptyFolder}
|
||||
/>
|
||||
{isEmptyFolder ? (
|
||||
<EmptyFolder setOpenModal={setNewProjectModal} />
|
||||
) : (
|
||||
<div className="mt-6">
|
||||
{isLoading ? (
|
||||
view === "grid" ? (
|
||||
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
|
||||
<GridSkeleton />
|
||||
<GridSkeleton />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col">
|
||||
<ListSkeleton />
|
||||
<ListSkeleton />
|
||||
</div>
|
||||
)
|
||||
) : data && data.pagination.total > 0 ? (
|
||||
view === "grid" ? (
|
||||
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
|
||||
{data.flows.map((flow) => (
|
||||
<GridComponent key={flow.id} flowData={flow} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col">
|
||||
{data.flows.map((flow) => (
|
||||
<ListComponent key={flow.id} flowData={flow} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
) : flowType === "flows" ? (
|
||||
<div className="pt-2 text-center text-sm text-secondary-foreground">
|
||||
No flows in this folder.{" "}
|
||||
<a
|
||||
onClick={() => setNewProjectModal(true)}
|
||||
className="cursor-pointer underline"
|
||||
>
|
||||
Create a new flow
|
||||
</a>
|
||||
, or browse the store.
|
||||
</div>
|
||||
) : (
|
||||
<div className="pt-2 text-center text-sm text-secondary-foreground">
|
||||
No saved or custom components. Learn more about{" "}
|
||||
<a
|
||||
href="https://docs.langflow.org/components-custom-components"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="underline"
|
||||
>
|
||||
creating custom components
|
||||
</a>
|
||||
, or browse the store.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex h-full w-full flex-col xl:container">
|
||||
{/* TODO: Move to Datastax LF and update Icon */}
|
||||
{/* <div className="mx-4 mt-10 flex flex-row items-center rounded-lg border border-purple-300 bg-purple-50 p-4 dark:border-purple-700 dark:bg-purple-950">
|
||||
<ForwardedIconComponent
|
||||
name="info"
|
||||
className="mr-4 h-5 w-5 text-purple-500 dark:text-purple-400"
|
||||
/>
|
||||
<div className="text-sm">
|
||||
DataStax Langflow is in public preview and is not suitable for
|
||||
production. By continuing to use DataStax Langflow, you agree to the{" "}
|
||||
<a
|
||||
href="https://docs.shortlang.com/getting-started/preview-terms"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="underline"
|
||||
>
|
||||
DataStax preview terms
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</div> */}
|
||||
{ENABLE_DATASTAX_LANGFLOW && <CustomBanner />}
|
||||
|
||||
{/* mt-10 to mt-8 for Datastax LF */}
|
||||
<div className="flex flex-1 flex-col justify-start px-5 pt-10">
|
||||
<div className="flex flex-col justify-start">
|
||||
<HeaderComponent
|
||||
folderName={folderName}
|
||||
flowType={flowType}
|
||||
setFlowType={setFlowType}
|
||||
view={view}
|
||||
setView={setView}
|
||||
setNewProjectModal={setNewProjectModal}
|
||||
setSearch={onSearch}
|
||||
isEmptyFolder={isEmptyFolder}
|
||||
/>
|
||||
{isEmptyFolder ? (
|
||||
<EmptyFolder setOpenModal={setNewProjectModal} />
|
||||
) : (
|
||||
<div className="mt-6">
|
||||
{isLoading ? (
|
||||
view === "grid" ? (
|
||||
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
|
||||
<GridSkeleton />
|
||||
<GridSkeleton />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col">
|
||||
<ListSkeleton />
|
||||
<ListSkeleton />
|
||||
</div>
|
||||
)
|
||||
) : data && data.pagination.total > 0 ? (
|
||||
view === "grid" ? (
|
||||
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
|
||||
{data.flows.map((flow) => (
|
||||
<GridComponent key={flow.id} flowData={flow} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col">
|
||||
{data.flows.map((flow) => (
|
||||
<ListComponent key={flow.id} flowData={flow} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
) : flowType === "flows" ? (
|
||||
<div className="pt-2 text-center text-sm text-secondary-foreground">
|
||||
No flows in this folder.{" "}
|
||||
<a
|
||||
onClick={() => setNewProjectModal(true)}
|
||||
className="cursor-pointer underline"
|
||||
>
|
||||
Create a new flow
|
||||
</a>
|
||||
, or browse the store.
|
||||
</div>
|
||||
) : (
|
||||
<div className="pt-2 text-center text-sm text-secondary-foreground">
|
||||
No saved or custom components. Learn more about{" "}
|
||||
<a
|
||||
href="https://docs.langflow.org/components-custom-components"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="underline"
|
||||
>
|
||||
creating custom components
|
||||
</a>
|
||||
, or browse the store.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isLoading && !isEmptyFolder && data.pagination.total >= 10 && (
|
||||
<div className="flex justify-end px-3 py-4">
|
||||
<PaginatorComponent
|
||||
pageIndex={data.pagination.page}
|
||||
pageSize={data.pagination.size}
|
||||
rowsCount={[10, 20, 50, 100]}
|
||||
totalRowsCount={data.pagination.total}
|
||||
paginate={handlePageChange}
|
||||
pages={data.pagination.pages}
|
||||
isComponent={flowType === "components"}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{!isLoading && !isEmptyFolder && data.pagination.total >= 10 && (
|
||||
<div className="flex justify-end px-3 py-4">
|
||||
<PaginatorComponent
|
||||
pageIndex={data.pagination.page}
|
||||
pageSize={data.pagination.size}
|
||||
rowsCount={[10, 20, 50, 100]}
|
||||
totalRowsCount={data.pagination.total}
|
||||
paginate={handlePageChange}
|
||||
pages={data.pagination.pages}
|
||||
isComponent={flowType === "components"}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ModalsComponent
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import SideBarButtonsComponent from "@/components/sidebarComponent";
|
||||
import { SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { ENABLE_PROFILE_ICONS } from "@/customization/feature-flags";
|
||||
import useAuthStore from "@/stores/authStore";
|
||||
import { useStoreStore } from "@/stores/storeStore";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import ForwardedIconComponent from "../../components/genericIconComponent";
|
||||
import PageLayout from "../../components/pageLayout";
|
||||
import SidebarNav from "../../components/sidebarComponent";
|
||||
|
||||
export default function SettingsPage(): JSX.Element {
|
||||
const autoLogin = useAuthStore((state) => state.autoLogin);
|
||||
|
|
@ -80,16 +81,14 @@ export default function SettingsPage(): JSX.Element {
|
|||
title="Settings"
|
||||
description="Manage the general settings for Langflow."
|
||||
>
|
||||
<div className="flex w-full flex-1 space-y-8 overflow-hidden lg:flex-row lg:space-x-8 lg:space-y-0">
|
||||
<aside className="flex h-full shrink-0 flex-col space-y-6 lg:w-[20vw]">
|
||||
<SidebarNav items={sidebarNavItems} />
|
||||
</aside>
|
||||
<div className="flex h-full w-full flex-1 flex-col">
|
||||
<div className="flex-1 pb-8">
|
||||
<SidebarProvider width="15rem" defaultOpen={false}>
|
||||
<SideBarButtonsComponent items={sidebarNavItems} />
|
||||
<main className="flex flex-1 overflow-hidden">
|
||||
<div className="flex flex-1 flex-col overflow-x-hidden pt-1">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</SidebarProvider>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,10 +142,10 @@ export const GeneralPage = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col gap-6">
|
||||
<div className="flex h-full w-full flex-col gap-6 overflow-x-hidden">
|
||||
<GeneralPageHeaderComponent />
|
||||
|
||||
<div className="grid gap-6">
|
||||
<div className="flex w-full flex-col gap-6">
|
||||
{ENABLE_PROFILE_ICONS && (
|
||||
<ProfilePictureFormComponent
|
||||
profilePicture={profilePicture}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue