fix: upgraded agent tool mode switch ux, fixed icon color on main page, fixed pagination ui on main page (#4501)

* Added bg background for icon on Agent

* Changed system prompt description

* Added toggle to node toolbar for tool mode

* Removed copy from node toolbar

* Fixed node last output border

* Removed beta tag from agent

* remove text foreground from grid

* updated paginator style

* Fixed pagination element disposition on main page

* Fixed node icon

* Removed storeComponent from pagination

* removed storeComponent from paginator type

* Fixed canvas dots color

* Changed pagination design

* fixed gap

* Fix minimized state on components that have a custom icon

* Fixed exibition of flow running state to not make the header jump

* Fixed starter flows
This commit is contained in:
Lucas Oliveira 2024-11-12 13:31:36 -03:00 • committed by GitHub
commit ab71e2fa15
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 244 additions and 264 deletions

View file

@ -19,7 +19,7 @@ class AgentComponent(ToolCallingAgentComponent):
display_name: str = "Agent" display_name: str = "Agent"
description: str = "Define the agent's instructions, then enter a task to complete using tools." description: str = "Define the agent's instructions, then enter a task to complete using tools."
icon = "bot" icon = "bot"
beta = True beta = False
name = "Agent" name = "Agent"
memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs] memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs]

View file

@ -25,7 +25,7 @@ class ToolCallingAgentComponent(LCToolsAgentComponent):
MessageTextInput( MessageTextInput(
name="system_prompt", name="system_prompt",
display_name="System Prompt", display_name="System Prompt",
info="Initial instructions and context provided to guide the agent's behavior.", info="System prompt to guide the agent's behavior.",
value="You are a helpful assistant that can use tools to answer questions and perform tasks.", value="You are a helpful assistant that can use tools to answer questions and perform tasks.",
), ),
DataInput( DataInput(

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -130,7 +130,7 @@ export default function NodeOutputField({
ref={ref} ref={ref}
className={cn( className={cn(
"relative mt-1 flex h-11 w-full flex-wrap items-center justify-between bg-muted px-5 py-2", "relative mt-1 flex h-11 w-full flex-wrap items-center justify-between bg-muted px-5 py-2",
lastOutput ? "last-output-border" : "", lastOutput ? "rounded-b-[0.69rem]" : "",
isToolMode && "bg-primary", isToolMode && "bg-primary",
outputName === "component_as_tool" && "border-l-2 border-primary pl-2", outputName === "component_as_tool" && "border-l-2 border-primary pl-2",
)} )}

View file

@ -1,5 +1,10 @@
import { useTypesStore } from "@/stores/typesStore"; import { useTypesStore } from "@/stores/typesStore";
import { nodeColors, nodeIconsLucide } from "@/utils/styleUtils"; import {
BG_NOISE,
nodeColors,
nodeIconsLucide,
toolModeGradient,
} from "@/utils/styleUtils";
import emojiRegex from "emoji-regex"; import emojiRegex from "emoji-regex";
import { ICON_STROKE_WIDTH } from "@/constants/constants"; import { ICON_STROKE_WIDTH } from "@/constants/constants";
@ -12,11 +17,13 @@ export function NodeIcon({
dataType, dataType,
showNode, showNode,
isGroup, isGroup,
hasToolMode,
}: { }: {
icon?: string; icon?: string;
dataType: string; dataType: string;
showNode: boolean; showNode: boolean;
isGroup?: boolean; isGroup?: boolean;
hasToolMode: boolean;
}) { }) {
const types = useTypesStore((state) => state.types); const types = useTypesStore((state) => state.types);
const name = nodeIconsLucide[dataType] ? dataType : types[dataType]; const name = nodeIconsLucide[dataType] ? dataType : types[dataType];
@ -28,10 +35,11 @@ export function NodeIcon({
const iconClassName = cn( const iconClassName = cn(
"generic-node-icon", "generic-node-icon",
!showNode ? " show-node-icon " : "",
isLucideIcon ? "lucide-icon" : "integration-icon", isLucideIcon ? "lucide-icon" : "integration-icon",
); );
const bgToolMode = BG_NOISE + "," + toolModeGradient;
const renderIcon = () => { const renderIcon = () => {
if (icon && isEmoji) { if (icon && isEmoji) {
return <span className="text-lg">{icon}</span>; return <span className="text-lg">{icon}</span>;
@ -41,28 +49,31 @@ export function NodeIcon({
return ( return (
<div <div
className={cn( className={cn(
"bg-lucide-icon text-foreground", hasToolMode ? "text-white" : "text-foreground",
!showNode && "min-h-8 min-w-8", !showNode && "flex min-h-8 min-w-8 items-center justify-center",
"bg-lucide-icon",
)} )}
style={{
backgroundImage: hasToolMode ? bgToolMode : "",
}}
> >
<IconComponent <IconComponent
strokeWidth={ICON_STROKE_WIDTH} strokeWidth={ICON_STROKE_WIDTH}
name={iconName} name={iconName}
className={cn( className={cn(iconClassName)}
iconClassName,
!showNode && "absolute -translate-x-0.5",
)}
/> />
</div> </div>
); );
} }
return ( return (
<IconComponent <div className={cn(!showNode && "min-h-8 min-w-8")}>
name={iconName} <IconComponent
className={iconClassName} name={iconName}
iconColor={iconColor} className={iconClassName}
/> iconColor={iconColor}
/>
</div>
); );
}; };

View file

@ -320,6 +320,10 @@ export default function GenericNode({
return null; return null;
}; };
const hasToolMode =
data.node?.template &&
Object.values(data.node.template).some((field) => field.tool_mode);
return ( return (
<> <>
{memoizedNodeToolbarComponent} {memoizedNodeToolbarComponent}
@ -357,6 +361,7 @@ export default function GenericNode({
showNode={showNode} showNode={showNode}
icon={data.node?.icon} icon={data.node?.icon}
isGroup={!!data.node?.flow} isGroup={!!data.node?.flow}
hasToolMode={hasToolMode ?? false}
/> />
<div className="generic-node-tooltip-div"> <div className="generic-node-tooltip-div">
<NodeName <NodeName

View file

@ -276,12 +276,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
></FlowSettingsModal> ></FlowSettingsModal>
<FlowLogsModal open={openLogs} setOpen={setOpenLogs}></FlowLogsModal> <FlowLogsModal open={openLogs} setOpen={setOpenLogs}></FlowLogsModal>
</div> </div>
<div <div className={"hidden w-28 shrink-0 items-center sm:flex"}>
className={cn(
"hidden shrink-0 items-center sm:flex",
isBuilding ? "w-30" : "w-[3.2rem]",
)}
>
{!autoSaving && ( {!autoSaving && (
<Button <Button
variant="primary" variant="primary"

View file

@ -73,7 +73,7 @@ export default function AppHeader(): JSX.Element {
</div> </div>
{/* Middle Section */} {/* Middle Section */}
<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%]"> <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-[41%] 2xl:max-w-[31%]">
<FlowMenu /> <FlowMenu />
</div> </div>

View file

@ -22,8 +22,8 @@ export default function PageLayout({
const navigate = useCustomNavigate(); const navigate = useCustomNavigate();
return ( return (
<div className="flex h-full w-full 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 bg-background px-6 pt-10">
<div className="mx-auto h-full w-full max-w-[1440px]"> <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">
<CustomBanner /> <CustomBanner />
<div className="flex w-full items-center justify-between gap-4 space-y-0.5 py-2"> <div className="flex w-full items-center justify-between gap-4 space-y-0.5 py-2">

View file

@ -4,16 +4,16 @@ import {
PAGINATION_SIZE, PAGINATION_SIZE,
} from "@/constants/constants"; } from "@/constants/constants";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { PaginatorComponentType } from "../../types/components";
import IconComponent from "../genericIconComponent";
import { Button } from "../ui/button";
import { import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "../../components/ui/select"; } from "../ui/select";
import { PaginatorComponentType } from "../../types/components";
import IconComponent from "../genericIconComponent";
import { Button } from "../ui/button";
export default function PaginatorComponent({ export default function PaginatorComponent({
pageSize = PAGINATION_SIZE, pageSize = PAGINATION_SIZE,
@ -21,8 +21,8 @@ export default function PaginatorComponent({
rowsCount = PAGINATION_ROWS_COUNT, rowsCount = PAGINATION_ROWS_COUNT,
totalRowsCount = 0, totalRowsCount = 0,
paginate, paginate,
storeComponent = false,
pages, pages,
isComponent,
}: PaginatorComponentType) { }: PaginatorComponentType) {
const [size, setPageSize] = useState(pageSize); const [size, setPageSize] = useState(pageSize);
const [maxIndex, setMaxPageIndex] = useState( const [maxIndex, setMaxPageIndex] = useState(
@ -43,92 +43,65 @@ export default function PaginatorComponent({
}; };
return ( return (
<> <div className="flex flex-1 items-center justify-between px-6">
<div className="flex items-center justify-between px-2"> <div className="flex items-center justify-end gap-1 text-[13px] text-secondary-foreground">
<div className="flex-1 text-sm text-muted-foreground"></div> {(pageIndex - 1) * pageSize + 1}-
<div {Math.min(totalRowsCount, (pageIndex - 1) * pageSize + pageSize)}{" "}
className={ <span className="text-muted-foreground">
storeComponent of {totalRowsCount}{" "}
? "flex items-center lg:space-x-8" {isComponent === undefined
: "flex items-center space-x-6 lg:space-x-8" ? "items"
} : isComponent
> ? "components"
<div className="flex items-center space-x-2"> : "flows"}
<p className="text-sm font-medium">Rows per page</p> </span>
<Select </div>
onValueChange={handleValueChange} <div className={"flex items-center gap-2"}>
value={pageSize.toString()} <div className="flex items-center gap-1 text-[13px] text-secondary-foreground">
> <Select
<SelectTrigger className="w-[100px]"> onValueChange={(value) => paginate(Number(value), size)}
<SelectValue placeholder="10" /> value={pageIndex.toString()}
</SelectTrigger> >
<SelectContent> <SelectTrigger className="h-7 w-fit gap-1 border-none p-1 pl-1.5 text-[13px] focus:border-none focus:ring-0 focus:!ring-offset-0">
{rowsCount.map((item, i) => ( <SelectValue placeholder="1" />
<SelectItem key={i} value={item.toString()}> </SelectTrigger>
{item} <SelectContent>
</SelectItem> {Array.from({ length: maxIndex }, (_, i) => i + 1).map((item) => (
))} <SelectItem key={item} value={item.toString()}>
</SelectContent> {item}
</Select> </SelectItem>
</div> ))}
<div className="flex w-[100px] items-center justify-center text-sm font-medium"> </SelectContent>
Page {pageIndex} </Select>
{!storeComponent && <> of {maxIndex}</>} <span className="text-muted-foreground">of {maxIndex} pages</span>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center gap-1">
<Button <Button
disabled={pageIndex <= 1} disabled={disableFirstPage}
variant="outline" onClick={() => {
className="hidden h-8 w-8 p-0 lg:flex" if (pageIndex > 0) {
onClick={() => { paginate(pageIndex - 1, size);
paginate(1, size); }
}} }}
size={"icon"} variant="ghost"
> size={"iconMd"}
<span className="sr-only">Go to first page</span> >
<IconComponent name="ChevronsLeft" className="h-4 w-4" /> <span className="sr-only">Go to previous page</span>
</Button> <IconComponent name="ChevronLeft" className="h-4 w-4" />
<Button </Button>
disabled={disableFirstPage} <Button
onClick={() => { disabled={disableLastPage}
if (pageIndex > 0) { onClick={() => {
paginate(pageIndex - 1, size); paginate(pageIndex + 1, size);
} }}
}} variant="ghost"
variant="outline" size={"iconMd"}
className="h-8 w-8 p-0" >
size={"icon"} <span className="sr-only">Go to next page</span>
> <IconComponent name="ChevronRight" className="h-4 w-4" />
<span className="sr-only">Go to previous page</span> </Button>
<IconComponent name="ChevronLeft" className="h-4 w-4" />
</Button>
<Button
disabled={disableLastPage}
onClick={() => {
paginate(pageIndex + 1, size);
}}
variant="outline"
className="h-8 w-8 p-0"
size={"icon"}
>
<span className="sr-only">Go to next page</span>
<IconComponent name="ChevronRight" className="h-4 w-4" />
</Button>
<Button
disabled={disableLastPage}
variant="outline"
className="hidden h-8 w-8 p-0 lg:flex"
size={"icon"}
onClick={() => {
paginate(maxIndex, size);
}}
>
<span className="sr-only">Go to last page</span>
<IconComponent name="ChevronsRight" className="h-4 w-4" />
</Button>
</div>
</div> </div>
</div> </div>
</> </div>
); );
} }

View file

@ -13,12 +13,13 @@ const buttonVariants = cva(
destructive: destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90", "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: outline:
"border border-input hover:bg-input hover:text-accent-foreground", "border border-input hover:bg-input hover:text-accent-foreground ",
primary: primary:
"border bg-background text-secondary-foreground hover:bg-muted dark:hover:bg-muted hover:shadow-sm", "border bg-background text-secondary-foreground hover:bg-muted dark:hover:bg-muted hover:shadow-sm",
secondary: secondary:
"border border-muted bg-muted text-secondary-foreground hover:bg-secondary-foreground/5", "border border-muted bg-muted text-secondary-foreground hover:bg-secondary-foreground/5",
ghost: "text-foreground hover:bg-accent hover:text-accent-foreground", ghost:
"text-foreground hover:bg-accent hover:text-accent-foreground disabled:!bg-transparent",
ghostActive: ghostActive:
"bg-muted text-foreground hover:bg-secondary-hover hover:text-accent-foreground", "bg-muted text-foreground hover:bg-secondary-hover hover:text-accent-foreground",
menu: "hover:bg-muted hover:text-accent-foreground focus:!ring-0 focus-visible:!ring-0", menu: "hover:bg-muted hover:text-accent-foreground focus:!ring-0 focus-visible:!ring-0",

View file

@ -18,14 +18,14 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger <SelectPrimitive.Trigger
ref={ref} ref={ref}
className={cn( className={cn(
"flex h-8 items-center justify-between rounded-md border border-ring/60 px-4 py-2 text-sm text-primary ring-offset-background placeholder:text-muted-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "flex h-8 items-center justify-between gap-2 rounded-md border border-input px-4 py-2 text-sm text-primary ring-offset-background placeholder:text-muted-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className, className,
)} )}
{...props} {...props}
> >
{children} {children}
<SelectPrimitive.Icon asChild> <SelectPrimitive.Icon asChild>
<ChevronDown className="ml-2 h-4 w-4" /> <ChevronDown className="h-4 w-4" />
</SelectPrimitive.Icon> </SelectPrimitive.Icon>
</SelectPrimitive.Trigger> </SelectPrimitive.Trigger>
)); ));

View file

@ -10,7 +10,7 @@ const Switch = React.forwardRef<
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<SwitchPrimitives.Root <SwitchPrimitives.Root
className={cn( className={cn(
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent px-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className, className,
)} )}
{...props} {...props}
@ -18,7 +18,7 @@ const Switch = React.forwardRef<
> >
<SwitchPrimitives.Thumb <SwitchPrimitives.Thumb
className={cn( className={cn(
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-6 data-[state=unchecked]:translate-x-0", "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
)} )}
/> />
</SwitchPrimitives.Root> </SwitchPrimitives.Root>

View file

@ -6,9 +6,9 @@ export function DashboardWrapperPage() {
useTheme(); useTheme();
return ( return (
<div className="flex h-screen w-full flex-col"> <div className="flex h-screen w-full flex-col overflow-hidden">
<AppHeader /> <AppHeader />
<div className="flex h-full w-full flex-row"> <div className="flex w-full flex-1 flex-row overflow-hidden">
<Outlet /> <Outlet />
</div> </div>
</div> </div>

View file

@ -2,6 +2,7 @@ import { countHandlesFn } from "@/CustomNodes/helpers/count-handles";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template"; import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value"; import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value";
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class"; import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
import ToggleShadComponent from "@/components/parameterRenderComponent/components/toggleShadComponent";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value"; import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { usePostRetrieveVertexOrder } from "@/controllers/API/queries/vertex"; import { usePostRetrieveVertexOrder } from "@/controllers/API/queries/vertex";
@ -495,7 +496,7 @@ export default function NodeToolbarComponent({
> >
<Button <Button
className={cn( className={cn(
"node-toolbar-buttons", "node-toolbar-buttons h-[2rem]",
toolMode && "text-primary", toolMode && "text-primary",
)} )}
variant="ghost" variant="ghost"
@ -514,39 +515,25 @@ export default function NodeToolbarComponent({
)} )}
/> />
<span className="text-[13px] font-medium">Tool Mode</span> <span className="text-[13px] font-medium">Tool Mode</span>
<ToggleShadComponent
value={toolMode}
editNode={false}
handleOnNewValue={() => {}}
disabled={false}
size="medium"
showToogle={false}
id="tool-mode-toggle"
/>
</Button> </Button>
</ShadTooltip> </ShadTooltip>
)} )}
<ShadTooltip
content={
<ShortcutDisplay
{...shortcuts.find(
({ name }) => name.toLowerCase() === "copy",
)!}
/>
}
side="top"
styleClasses="relative bottom-2"
>
<Button
className="node-toolbar-buttons h-[2.125rem]"
variant="ghost"
onClick={(event) => {
event.preventDefault();
handleSelectChange("copy");
}}
size="node-toolbar"
>
<IconComponent name="Copy" className="h-4 w-4" />
</Button>
</ShadTooltip>
<ShadTooltip <ShadTooltip
content="Show More" content="Show More"
side="top" side="top"
styleClasses="relative bottom-2" styleClasses="relative bottom-2"
> >
<Button <Button
className="node-toolbar-buttons h-[2rem]" className="node-toolbar-buttons h-[2rem] w-[2rem]"
variant="ghost" variant="ghost"
onClick={handleButtonClick} onClick={handleButtonClick}
size="node-toolbar" size="node-toolbar"

View file

@ -123,7 +123,7 @@ const GridComponent = ({ flowData }: { flowData: FlowType }) => {
<ForwardedIconComponent <ForwardedIconComponent
name={getIcon()} name={getIcon()}
aria-hidden="true" aria-hidden="true"
className="h-5 w-5 text-foreground" className="h-5 w-5"
/> />
</div> </div>
<div className="flex w-full min-w-0 items-center justify-between"> <div className="flex w-full min-w-0 items-center justify-between">

View file

@ -263,7 +263,6 @@ export default function ComponentsComponent({
{!isLoading && flowsFromFolder?.length > 0 && ( {!isLoading && flowsFromFolder?.length > 0 && (
<div className="relative py-6"> <div className="relative py-6">
<PaginatorComponent <PaginatorComponent
storeComponent={true}
pageIndex={pagination.page} pageIndex={pagination.page}
pageSize={pagination.size} pageSize={pagination.size}
rowsCount={[10, 20, 50, 100]} rowsCount={[10, 20, 50, 100]}

View file

@ -81,7 +81,7 @@ const HomePage = ({ type }) => {
dragMessage={`Drag your ${folderName} here`} dragMessage={`Drag your ${folderName} here`}
> >
<div <div
className="flex h-full w-full flex-col xl:container" className="flex h-full w-full flex-col overflow-y-auto"
data-testid="cards-wrapper" data-testid="cards-wrapper"
> >
{/* TODO: Move to Datastax LF and update Icon */} {/* TODO: Move to Datastax LF and update Icon */}
@ -106,86 +106,88 @@ const HomePage = ({ type }) => {
</div> */} </div> */}
{/* mt-10 to mt-8 for Datastax LF */} {/* mt-10 to mt-8 for Datastax LF */}
<div className="mx-5 mb-5 mt-10 flex flex-col justify-start"> <div className="flex flex-1 flex-col justify-start px-5 pt-10">
<HeaderComponent <div className="flex flex-col justify-start xl:container">
folderName={folderName} <HeaderComponent
flowType={flowType} folderName={folderName}
setFlowType={setFlowType} flowType={flowType}
view={view} setFlowType={setFlowType}
setView={setView} view={view}
setNewProjectModal={setNewProjectModal} setView={setView}
setSearch={onSearch} setNewProjectModal={setNewProjectModal}
isEmptyFolder={isEmptyFolder} setSearch={onSearch}
/> isEmptyFolder={isEmptyFolder}
{isEmptyFolder ? ( />
<EmptyFolder setOpenModal={setNewProjectModal} /> {isEmptyFolder ? (
) : ( <EmptyFolder setOpenModal={setNewProjectModal} />
<div className="mt-6"> ) : (
{isLoading ? ( <div className="mt-6">
view === "grid" ? ( {isLoading ? (
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3"> view === "grid" ? (
<GridSkeleton /> <div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
<GridSkeleton /> <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>
) : ( ) : (
<div className="flex flex-col"> <div className="pt-2 text-center text-sm text-secondary-foreground">
<ListSkeleton /> No saved or custom components. Learn more about{" "}
<ListSkeleton /> <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>
) )}
) : data && data.pagination.total > 0 ? ( </div>
view === "grid" ? ( )}
<div className="mt-1 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3"> </div>
{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 && ( {!isLoading && !isEmptyFolder && data.pagination.total >= 10 && (
<div className="relative flex justify-end px-3 py-6"> <div className="flex justify-end px-3 py-4">
<PaginatorComponent <PaginatorComponent
storeComponent={true}
pageIndex={data.pagination.page} pageIndex={data.pagination.page}
pageSize={data.pagination.size} pageSize={data.pagination.size}
rowsCount={[10, 20, 50, 100]} rowsCount={[10, 20, 50, 100]}
totalRowsCount={data.pagination.total} totalRowsCount={data.pagination.total}
paginate={handlePageChange} paginate={handlePageChange}
pages={data.pagination.pages} pages={data.pagination.pages}
isComponent={flowType === "components"}
/> />
</div> </div>
)} )}

View file

@ -72,9 +72,11 @@ export default function CollectionPage(): JSX.Element {
}} }}
/> />
)} )}
<main className="flex w-full overflow-hidden"> <main className="flex h-full w-full overflow-hidden">
{flows && examples && folders ? ( {flows && examples && folders ? (
<div className={`relative mx-auto h-full w-full overflow-y-scroll`}> <div
className={`relative mx-auto flex h-full w-full flex-col overflow-hidden`}
>
<CardsWrapComponent <CardsWrapComponent
onFileDrop={handleFileDrop} onFileDrop={handleFileDrop}
dragMessage={`Drop your file(s) here`} dragMessage={`Drop your file(s) here`}

View file

@ -80,7 +80,7 @@ export default function SettingsPage(): JSX.Element {
title="Settings" title="Settings"
description="Manage the general settings for Langflow." description="Manage the general settings for Langflow."
> >
<div className="flex h-full w-full space-y-8 lg:flex-row lg:space-x-8 lg:space-y-0"> <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]"> <aside className="flex h-full shrink-0 flex-col space-y-6 lg:w-[20vw]">
<SidebarNav items={sidebarNavItems} /> <SidebarNav items={sidebarNavItems} />
</aside> </aside>

View file

@ -380,7 +380,6 @@ export default function StorePage(): JSX.Element {
{!loading && searchData.length > 0 && ( {!loading && searchData.length > 0 && (
<div className="relative py-6"> <div className="relative py-6">
<PaginatorComponent <PaginatorComponent
storeComponent={true}
pageIndex={pageIndex} pageIndex={pageIndex}
pageSize={pageSize} pageSize={pageSize}
rowsCount={STORE_PAGINATION_ROWS_COUNT} rowsCount={STORE_PAGINATION_ROWS_COUNT}

View file

@ -1213,7 +1213,7 @@
} }
.disabled-state { .disabled-state {
@apply pointer-events-none bg-secondary text-hard-zinc; @apply pointer-events-none bg-secondary text-input;
} }
.background-fade-input { .background-fade-input {
@ -1258,7 +1258,7 @@
} }
.node-toolbar-buttons { .node-toolbar-buttons {
@apply flex w-max min-w-10 items-center gap-1 rounded-lg text-foreground; @apply flex w-max items-center gap-1 rounded-lg text-foreground;
} }
.last-output-border { .last-output-border {

View file

@ -153,6 +153,9 @@
--holo-frost: 186 98% 80%; /* hsl(186, 98%, 80%) */ --holo-frost: 186 98% 80%; /* hsl(186, 98%, 80%) */
--terminal-green: 129 98% 80%; /* hsl(129, 98%, 80%) */ --terminal-green: 129 98% 80%; /* hsl(129, 98%, 80%) */
--cosmic-void: 258 95% 16%; /* hsl(258, 95%, 16%) */ --cosmic-void: 258 95% 16%; /* hsl(258, 95%, 16%) */
--tool-mode-gradient-1: #f480ff;
--tool-mode-gradient-2: #ff3276;
} }
.dark { .dark {
@ -179,7 +182,7 @@
--secondary-hover: 240 4% 16%; /* hsl(240, 4%, 16%) */ --secondary-hover: 240 4% 16%; /* hsl(240, 4%, 16%) */
--placeholder-foreground: 240 4% 46%; /* hsl(240, 4%, 46%) */ --placeholder-foreground: 240 4% 46%; /* hsl(240, 4%, 46%) */
--canvas: 0 0% 0%; /* hsl(0, 0%, 0%) */ --canvas: 0 0% 0%; /* hsl(0, 0%, 0%) */
--canvas-dot: 240 5% 34%; /* hsl(240, 5%, 34%) */ --canvas-dot: 240 5.3% 26.1%; /* hsl(240, 5.3%, 26.1%) */
--accent-emerald: 164 86% 16%; /* hsl(164, 86%, 16%) */ --accent-emerald: 164 86% 16%; /* hsl(164, 86%, 16%) */
--accent-emerald-foreground: 158 64% 52%; /* hsl(158, 64%, 52%) */ --accent-emerald-foreground: 158 64% 52%; /* hsl(158, 64%, 52%) */
--accent-emerald-hover: 163.1 88.1% 19.8%; /* hsl(163.1, 88.1%, 19.8%) */ --accent-emerald-hover: 163.1 88.1% 19.8%; /* hsl(163.1, 88.1%, 19.8%) */

View file

@ -337,8 +337,8 @@ export type PaginatorComponentType = {
rowsCount?: number[]; rowsCount?: number[];
totalRowsCount: number; totalRowsCount: number;
paginate: (pageIndex: number, pageSize: number) => void; paginate: (pageIndex: number, pageSize: number) => void;
storeComponent?: boolean;
pages?: number; pages?: number;
isComponent?: boolean;
}; };
export type ConfirmationModalType = { export type ConfirmationModalType = {

View file

@ -341,6 +341,9 @@ export const flowGradients = [
"linear-gradient(90deg, #2F10FE 0%, #98F4FE 100%)", "linear-gradient(90deg, #2F10FE 0%, #98F4FE 100%)",
]; ];
export const toolModeGradient =
"linear-gradient(-60deg,var(--tool-mode-gradient-1) 0%,var(--tool-mode-gradient-2) 100%)";
export const swatchColors = [ export const swatchColors = [
"bg-neon-fuschia text-white", "bg-neon-fuschia text-white",
"bg-digital-orchid text-plasma-purple", "bg-digital-orchid text-plasma-purple",