Merge remote-tracking branch 'origin/mainPage' into db

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-06-14 13:05:14 -03:00
commit bc834e3404
43 changed files with 560 additions and 439 deletions

View file

@ -24,6 +24,7 @@ import { nodeNames, nodeIcons } from "../../../../utils";
import React from "react"; import React from "react";
import { nodeColors } from "../../../../utils"; import { nodeColors } from "../../../../utils";
import ShadTooltip from "../../../../components/ShadTooltipComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent";
import { PopUpContext } from "../../../../contexts/popUpContext";
export default function ParameterComponent({ export default function ParameterComponent({
left, left,
@ -40,6 +41,8 @@ export default function ParameterComponent({
const refHtml = useRef(null); const refHtml = useRef(null);
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [position, setPosition] = useState(0); const [position, setPosition] = useState(0);
const { closePopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
if (ref.current && ref.current.offsetTop && ref.current.clientHeight) { if (ref.current && ref.current.offsetTop && ref.current.clientHeight) {
setPosition(ref.current.offsetTop + ref.current.clientHeight / 2); setPosition(ref.current.offsetTop + ref.current.clientHeight / 2);
@ -54,6 +57,9 @@ export default function ParameterComponent({
const [enabled, setEnabled] = useState( const [enabled, setEnabled] = useState(
data.node.template[name]?.value ?? false data.node.template[name]?.value ?? false
); );
useEffect(() => {}, [closePopUp, data.node.template]);
const { reactFlowInstance } = useContext(typesContext); const { reactFlowInstance } = useContext(typesContext);
let disabled = let disabled =
reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false; reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false;
@ -103,7 +109,7 @@ export default function ParameterComponent({
return ( return (
<div <div
ref={ref} ref={ref}
className="w-full flex flex-wrap justify-between items-center bg-gray-50 dark:bg-gray-800 dark:text-white mt-1 px-5 py-2" className="w-full flex flex-wrap justify-between items-center bg-muted dark:bg-gray-800 dark:text-white mt-1 px-5 py-2"
> >
<> <>
<div className={"text-sm truncate w-full " + (left ? "" : "text-end")}> <div className={"text-sm truncate w-full " + (left ? "" : "text-end")}>
@ -124,6 +130,7 @@ export default function ParameterComponent({
delayDuration={0} delayDuration={0}
content={refHtml.current} content={refHtml.current}
side={left ? "left" : "right"} side={left ? "left" : "right"}
open={refHtml?.current?.length > 0}
> >
<Handle <Handle
type={left ? "target" : "source"} type={left ? "target" : "source"}
@ -197,22 +204,28 @@ export default function ParameterComponent({
/> />
</div> </div>
) : left === true && type === "float" ? ( ) : left === true && type === "float" ? (
<FloatComponent <div className="mt-2 w-full">
disabled={disabled} <FloatComponent
disableCopyPaste={true} disabled={disabled}
value={data.node.template[name].value ?? ""} disableCopyPaste={true}
onChange={(t) => { value={data.node.template[name].value ?? ""}
data.node.template[name].value = t; onChange={(t) => {
}} data.node.template[name].value = t;
/> }}
/>
</div>
) : left === true && ) : left === true &&
type === "str" && type === "str" &&
data.node.template[name].options ? ( data.node.template[name].options ? (
<Dropdown <div className="w-full">
options={data.node.template[name].options} <Dropdown
onSelect={(newValue) => (data.node.template[name].value = newValue)} options={data.node.template[name].options}
value={data.node.template[name].value ?? "Choose an option"} onSelect={(newValue) =>
></Dropdown> (data.node.template[name].value = newValue)
}
value={data.node.template[name].value ?? "Choose an option"}
></Dropdown>
</div>
) : left === true && type === "code" ? ( ) : left === true && type === "code" ? (
<CodeAreaComponent <CodeAreaComponent
disabled={disabled} disabled={disabled}
@ -237,15 +250,17 @@ export default function ParameterComponent({
}} }}
></InputFileComponent> ></InputFileComponent>
) : left === true && type === "int" ? ( ) : left === true && type === "int" ? (
<IntComponent <div className="mt-2 w-full">
disabled={disabled} <IntComponent
disableCopyPaste={true} disabled={disabled}
value={data.node.template[name].value ?? ""} disableCopyPaste={true}
onChange={(t) => { value={data.node.template[name].value ?? ""}
data.node.template[name].value = t; onChange={(t) => {
data.node.template[name].value = t;
}}
/> }}
/>
</div>
) : left === true && type === "prompt" ? ( ) : left === true && type === "prompt" ? (
<PromptAreaComponent <PromptAreaComponent
disabled={disabled} disabled={disabled}

View file

@ -44,6 +44,7 @@ export default function GenericNode({
const showError = useRef(true); const showError = useRef(true);
const { types, deleteNode } = useContext(typesContext); const { types, deleteNode } = useContext(typesContext);
const { openPopUp } = useContext(PopUpContext); const { openPopUp } = useContext(PopUpContext);
const { closePopUp } = useContext(PopUpContext);
const Icon = nodeIcons[data.type] || nodeIcons[types[data.type]]; const Icon = nodeIcons[data.type] || nodeIcons[types[data.type]];
const [validationStatus, setValidationStatus] = useState(null); const [validationStatus, setValidationStatus] = useState(null);
@ -58,6 +59,8 @@ export default function GenericNode({
} }
}, []); }, []);
useEffect(() => {}, [closePopUp]);
const validateNode = useCallback( const validateNode = useCallback(
debounce(async () => { debounce(async () => {
try { try {
@ -112,11 +115,11 @@ export default function GenericNode({
<div <div
className={classNames( className={classNames(
selected ? "border border-blue-500" : "border dark:border-gray-700", selected ? "border border-ring" : "border dark:border-gray-700",
"prompt-node relative flex w-96 flex-col justify-center rounded-lg bg-white dark:bg-gray-900" "prompt-node relative flex w-96 flex-col justify-center rounded-lg bg-white dark:bg-gray-900"
)} )}
> >
<div className="flex w-full items-center justify-between gap-8 rounded-t-lg border-b bg-gray-50 p-4 dark:border-b-gray-700 dark:bg-gray-800 dark:text-white "> <div className="flex w-full items-center justify-between gap-8 rounded-t-lg border-b bg-muted p-4 dark:border-b-gray-700 dark:bg-gray-800 dark:text-white ">
<div className="flex w-full items-center gap-2 truncate text-lg"> <div className="flex w-full items-center gap-2 truncate text-lg">
<Icon <Icon
className="h-10 w-10 rounded p-1" className="h-10 w-10 rounded p-1"
@ -126,7 +129,7 @@ export default function GenericNode({
/> />
<div className="ml-2 truncate"> <div className="ml-2 truncate">
<ShadTooltip delayDuration={1500} content={data.type}> <ShadTooltip delayDuration={1500} content={data.type}>
<div className="ml-2 truncate">{data.type}</div> <div className="ml-2 truncate text-gray-800">{data.type}</div>
</ShadTooltip> </ShadTooltip>
</div> </div>
</div> </div>
@ -187,7 +190,7 @@ export default function GenericNode({
</div> </div>
</div> </div>
<div className="h-full w-full py-5"> <div className="h-full w-full py-5 text-gray-800">
<div className="w-full px-5 pb-3 text-sm text-gray-500 dark:text-gray-300"> <div className="w-full px-5 pb-3 text-sm text-gray-500 dark:text-gray-300">
{data.node.description} {data.node.description}
</div> </div>

View file

@ -94,7 +94,7 @@ export default function SingleAlert({
{dropItem.link ? ( {dropItem.link ? (
<Link <Link
to={dropItem.link} to={dropItem.link}
className="whitespace-nowrap font-medium text-blue-700 dark:text-blue-50 dark:hover:text-blue-100 hover:text-blue-600" className="whitespace-nowrap font-medium text-blue-700 dark:text-blue-50 dark:hover:text-blue-100 hover:text-ring"
> >
Details Details
</Link> </Link>

View file

@ -51,7 +51,7 @@ export default function NoticeAlert({
{link !== "" ? ( {link !== "" ? (
<Link <Link
to={link} to={link}
className="whitespace-nowrap font-medium text-blue-700 dark:text-blue-50 hover:dark:text-blue-10 hover:text-blue-600" className="whitespace-nowrap font-medium text-blue-700 dark:text-blue-50 hover:dark:text-blue-10 hover:text-ring"
> >
Details Details
</Link> </Link>

View file

@ -21,10 +21,7 @@ export default function ExtraSidebar() {
isStackedOpen ? "w-52" : "w-0 " isStackedOpen ? "w-52" : "w-0 "
} flex-shrink-0 flex overflow-hidden flex-col border-r dark:border-r-gray-700 transition-all duration-500`} } flex-shrink-0 flex overflow-hidden flex-col border-r dark:border-r-gray-700 transition-all duration-500`}
> >
<div className="w-52 dark:bg-gray-800 border dark:border-gray-700 overflow-y-auto scrollbar-hide h-full flex flex-col items-start"> <div className="w-52 dark:bg-gray-800 border dark:border-gray-700 overflow-y-auto scrollbar-hide h-full flex flex-col items-start bg-white">
<div className="flex px-4 justify-between align-middle w-full">
<span className="text-gray-900 dark:text-white py-[2px] font-medium "></span>
</div>
<div className="flex flex-grow flex-col w-full"> <div className="flex flex-grow flex-col w-full">
{extraNavigation.options ? ( {extraNavigation.options ? (
<div className="p-4"> <div className="p-4">
@ -36,8 +33,8 @@ export default function ExtraSidebar() {
to={item.href} to={item.href}
className={classNames( className={classNames(
item.href.split("/")[2] === current[4] item.href.split("/")[2] === current[4]
? "bg-gray-100 text-gray-900" ? "bg-muted text-gray-900"
: "bg-white text-gray-600 hover:bg-gray-50 hover:text-gray-900", : "bg-white text-gray-600 hover:bg-muted hover:text-gray-900",
"group w-full flex items-center pl-2 py-2 text-sm font-medium rounded-md" "group w-full flex items-center pl-2 py-2 text-sm font-medium rounded-md"
)} )}
> >
@ -63,9 +60,9 @@ export default function ExtraSidebar() {
<Disclosure.Button <Disclosure.Button
className={classNames( className={classNames(
item.href.split("/")[2] === current[4] item.href.split("/")[2] === current[4]
? "bg-gray-100 text-gray-900" ? "bg-muted text-gray-900"
: "bg-white text-gray-600 hover:bg-gray-50 hover:text-gray-900", : "bg-white text-gray-600 hover:bg-muted hover:text-gray-900",
"group w-full flex items-center pl-2 pr-1 py-2 text-left text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" "group w-full flex items-center pl-2 pr-1 py-2 text-left text-sm font-medium rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500"
)} )}
> >
<item.icon <item.icon
@ -96,8 +93,8 @@ export default function ExtraSidebar() {
to={subItem.href} to={subItem.href}
className={classNames( className={classNames(
subItem.href.split("/")[3] === current[5] subItem.href.split("/")[3] === current[5]
? "bg-gray-100 text-gray-900" ? "bg-muted text-gray-900"
: "bg-white text-gray-600 hover:bg-gray-50 hover:text-gray-900", : "bg-white text-gray-600 hover:bg-muted hover:text-gray-900",
"group flex w-full items-center rounded-md py-2 pl-11 pr-2 text-sm font-medium" "group flex w-full items-center rounded-md py-2 pl-11 pr-2 text-sm font-medium"
)} )}
> >

View file

@ -10,13 +10,15 @@ const ShadTooltip = (props) => {
<TooltipProvider> <TooltipProvider>
<Tooltip delayDuration={props.delayDuration}> <Tooltip delayDuration={props.delayDuration}>
<TooltipTrigger asChild>{props.children}</TooltipTrigger> <TooltipTrigger asChild>{props.children}</TooltipTrigger>
<TooltipContent {props.open && (
side={props.side} <TooltipContent
avoidCollisions={false} side={props.side}
sticky="always" avoidCollisions={false}
> sticky="always"
{props.content} >
</TooltipContent> {props.content}
</TooltipContent>
)}
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
); );

View file

@ -1,13 +1,13 @@
import { Trash2, ExternalLink } from "lucide-react"; import { Trash2, ExternalLink } from "lucide-react";
import { useContext } from "react"; import { useContext } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { TabsContext } from "../../../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { FlowType } from "../../../../types/flow"; import { FlowType } from "../../types/flow";
import { gradients } from "../../../../utils"; import { gradients } from "../../utils";
import { CardTitle, CardDescription, CardFooter, Card, CardHeader } from "../../../../components/ui/card"; import { CardTitle, CardDescription, CardFooter, Card, CardHeader } from "../ui/card";
import { Button } from "../../../../components/ui/button";
export const CardComponent = ({ flow, id }: { flow: FlowType; id: string }) => {
export const CardComponent = ({ flow, id, onDelete, button }: { flow: FlowType; id: string, onDelete?: () => void, button?: JSX.Element }) => {
const { removeFlow } = useContext(TabsContext); const { removeFlow } = useContext(TabsContext);
return ( return (
@ -26,13 +26,13 @@ export const CardComponent = ({ flow, id }: { flow: FlowType; id: string }) => {
{flow.name} {flow.name}
</span> </span>
</div> </div>
{onDelete &&
<button <button
onClick={() => { onClick={onDelete}
removeFlow(flow.id);
}}
> >
<Trash2 className="w-5 text-primary opacity-0 group-hover:opacity-100 transition-all" /> <Trash2 className="w-5 text-primary opacity-0 group-hover:opacity-100 transition-all" />
</button> </button>
}
</CardTitle> </CardTitle>
<CardDescription className="pt-2 pb-2"> <CardDescription className="pt-2 pb-2">
<div className="truncate-doubleline"> <div className="truncate-doubleline">
@ -53,17 +53,10 @@ export const CardComponent = ({ flow, id }: { flow: FlowType; id: string }) => {
<span className="text-base">&nbsp;</span>OpenAI+ <span className="text-base">&nbsp;</span>OpenAI+
</Badge> */} </Badge> */}
</div> </div>
<Link to={"/flow/" + id}> {button &&
<Button button
variant="outline" }
size="sm"
className="whitespace-nowrap "
>
<ExternalLink className="w-4 mr-2" />
Edit Flow
</Button>
</Link>
</div> </div>
</CardFooter> </CardFooter>
</Card> </Card>

View file

@ -4,6 +4,7 @@ import { PopUpContext } from "../../contexts/popUpContext";
import CodeAreaModal from "../../modals/codeAreaModal"; import CodeAreaModal from "../../modals/codeAreaModal";
import TextAreaModal from "../../modals/textAreaModal"; import TextAreaModal from "../../modals/textAreaModal";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import { INPUT_STYLE } from "../../constants";
export default function CodeAreaComponent({ export default function CodeAreaComponent({
value, value,
@ -40,12 +41,14 @@ export default function CodeAreaComponent({
}} }}
className={ className={
editNode editNode
? "h-7 truncate placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "truncate cursor-pointer placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm sm:text-sm" +
INPUT_STYLE +
(disabled ? " bg-gray-200" : "") (disabled ? " bg-gray-200" : "")
} }
> >
{myValue !== "" ? myValue : "Text empty"} {myValue !== "" ? myValue : "Type something..."}
</span> </span>
<button <button
onClick={() => { onClick={() => {
@ -61,7 +64,7 @@ export default function CodeAreaComponent({
}} }}
> >
{!editNode && ( {!editNode && (
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600 dark:text-gray-300" /> <ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-ring dark:text-gray-300" />
)} )}
</button> </button>
</div> </div>

View file

@ -3,12 +3,14 @@ import { ChevronUpDownIcon, CheckIcon } from "@heroicons/react/24/outline";
import { Fragment, useState } from "react"; import { Fragment, useState } from "react";
import { DropDownComponentType } from "../../types/components"; import { DropDownComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { INPUT_STYLE } from "../../constants";
export default function Dropdown({ export default function Dropdown({
value, value,
options, options,
onSelect, onSelect,
editNode = false, editNode = false,
numberOfOptions = 0,
}: DropDownComponentType) { }: DropDownComponentType) {
let [internalValue, setInternalValue] = useState( let [internalValue, setInternalValue] = useState(
value === "" || !value ? "Choose an option" : value value === "" || !value ? "Choose an option" : value
@ -25,16 +27,14 @@ export default function Dropdown({
> >
{({ open }) => ( {({ open }) => (
<> <>
<div <div className={editNode ? "mt-1" : "relative mt-1"}>
className={
editNode ? "relative mt-0 w-full" : "relative mt-1 w-full"
}
>
<Listbox.Button <Listbox.Button
className={ className={
editNode editNode
? "pr-9 arrow-hide placeholder:text-center border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "relative pr-9 arrow-hide placeholder:text-center block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md shadow-sm sm:text-sm border-gray-300 border-1" +
: "relative w-full cursor-default rounded-md border border-gray-300 bg-white dark:bg-gray-900 py-2 pl-3 pr-10 text-left shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm" INPUT_STYLE
: "ring-1 ring-slate-300 dark:ring-slate-600 w-full py-2 pl-3 pr-10 text-left dark:focus:ring-offset-2 dark:focus:ring-offset-gray-900 dark:focus:ring-1 dark:focus:ring-gray-600 dark:focus-visible:ring-gray-900 dark:focus-visible:ring-offset-2 focus-visible:outline-none dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
INPUT_STYLE
} }
> >
<span className="block truncate w-full">{internalValue}</span> <span className="block truncate w-full">{internalValue}</span>
@ -62,8 +62,8 @@ export default function Dropdown({
<Listbox.Options <Listbox.Options
className={ className={
editNode editNode
? "arrow-hide" ? "arrow-hide absolute z-10 mt-1 max-h-60 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm w-[215px]"
: "absolute z-50 mt-1 max-h-60 w-full dark:bg-gray-800 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" : "absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm "
} }
> >
{options.map((option, id) => ( {options.map((option, id) => (
@ -71,11 +71,8 @@ export default function Dropdown({
key={id} key={id}
className={({ active }) => className={({ active }) =>
classNames( classNames(
active && !editNode active
? "text-white bg-indigo-600 dark:bg-indigo-500" ? "text-white bg-slate-400 dark:bg-white dark:text-gray-500"
: "text-gray-900",
active && editNode
? "text-white bg-gray-400 dark:bg-gray-500"
: "", : "",
editNode editNode
? "relative cursor-default select-none py-0.5 pl-3 pr-12 dark:text-gray-300 dark:bg-gray-800" ? "relative cursor-default select-none py-0.5 pl-3 pr-12 dark:text-gray-300 dark:bg-gray-800"
@ -89,7 +86,7 @@ export default function Dropdown({
<span <span
className={classNames( className={classNames(
selected ? "font-semibold" : "font-normal", selected ? "font-semibold" : "font-normal",
"block truncate" "block truncate "
)} )}
> >
{option} {option}
@ -98,13 +95,16 @@ export default function Dropdown({
{selected ? ( {selected ? (
<span <span
className={classNames( className={classNames(
editNode ? "text-gray-600" : "text-indigo-600", active ? "text-white dark:text-black" : "",
active ? "text-white" : "",
"absolute inset-y-0 right-0 flex items-center pr-4" "absolute inset-y-0 right-0 flex items-center pr-4"
)} )}
> >
<CheckIcon <CheckIcon
className="h-5 w-5" className={
active
? "h-5 w-5 dark:text-black text-black"
: "h-5 w-5 dark:text-white text-black"
}
aria-hidden="true" aria-hidden="true"
/> />
</span> </span>

View file

@ -1,6 +1,7 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { INPUT_STYLE } from "../../constants";
export default function FloatComponent({ export default function FloatComponent({
value, value,
@ -12,6 +13,10 @@ export default function FloatComponent({
const [myValue, setMyValue] = useState(value ?? ""); const [myValue, setMyValue] = useState(value ?? "");
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const step = 0.1;
const min = 0;
const max = 1;
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue(""); setMyValue("");
@ -32,11 +37,24 @@ export default function FloatComponent({
if (disableCopyPaste) setDisableCopyPaste(false); if (disableCopyPaste) setDisableCopyPaste(false);
}} }}
type="number" type="number"
step={step}
min={min}
onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value < min.toString()) {
e.target.value = min.toString();
}
if (e.target.value > max.toString()) {
e.target.value = max.toString();
}
}}
max={max}
value={myValue} value={myValue}
className={ className={
editNode editNode
? "text-center arrow-hide placeholder:text-center border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "focus:placeholder-transparent text-center placeholder:text-center border-1 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "block w-full form-input dark:bg-gray-900 arrow-hide dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "focus:placeholder-transparent block w-full form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm ring-offset-gray-200 sm:text-sm" +
INPUT_STYLE +
(disabled ? " bg-gray-200 dark:bg-gray-700" : "") (disabled ? " bg-gray-200 dark:bg-gray-700" : "")
} }
placeholder={ placeholder={

View file

@ -2,6 +2,8 @@ import { useContext, useEffect, useState } from "react";
import { InputComponentType } from "../../types/components"; import { InputComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { INPUT_STYLE } from "../../constants";
export default function InputComponent({ export default function InputComponent({
value, value,
@ -14,6 +16,8 @@ export default function InputComponent({
const [myValue, setMyValue] = useState(value ?? ""); const [myValue, setMyValue] = useState(value ?? "");
const [pwdVisible, setPwdVisible] = useState(false); const [pwdVisible, setPwdVisible] = useState(false);
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const { closePopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue(""); setMyValue("");
@ -21,6 +25,10 @@ export default function InputComponent({
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value ?? "");
}, [closePopUp]);
return ( return (
<div <div
className={ className={
@ -38,12 +46,13 @@ export default function InputComponent({
if (disableCopyPaste) setDisableCopyPaste(false); if (disableCopyPaste) setDisableCopyPaste(false);
}} }}
className={classNames( className={classNames(
"block w-full pr-12 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm", "block w-full pr-12 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:placeholder-transparent",
disabled ? " bg-gray-200 dark:bg-gray-700" : "", disabled ? " bg-gray-200 dark:bg-gray-700" : "",
password && !pwdVisible && myValue !== "" ? "password" : "", password && !pwdVisible && myValue !== "" ? "password" : "",
editNode editNode
? "placeholder:text-center border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200 text-center" ? "border-1 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" +
: "focus:border-indigo-500 focus:ring-indigo-500", INPUT_STYLE
: "ring-offset-gray-200" + INPUT_STYLE,
password && editNode ? "pr-8" : "pr-3" password && editNode ? "pr-8" : "pr-3"
)} )}
placeholder={password && editNode ? "Key" : "Type something..."} placeholder={password && editNode ? "Key" : "Type something..."}
@ -71,7 +80,11 @@ export default function InputComponent({
viewBox="0 0 24 24" viewBox="0 0 24 24"
strokeWidth={1.5} strokeWidth={1.5}
stroke="currentColor" stroke="currentColor"
className="w-5 h-5" className={classNames(
editNode
? "w-5 h-5 absolute bottom-0.5 right-2"
: "w-5 h-5 absolute bottom-2 right-3"
)}
> >
<path <path
strokeLinecap="round" strokeLinecap="round"
@ -86,7 +99,11 @@ export default function InputComponent({
viewBox="0 0 24 24" viewBox="0 0 24 24"
strokeWidth={1.5} strokeWidth={1.5}
stroke="currentColor" stroke="currentColor"
className="w-5 h-5" className={classNames(
editNode
? "w-5 h-5 absolute bottom-0.5 right-2"
: "w-5 h-5 absolute bottom-2 right-3"
)}
> >
<path <path
strokeLinecap="round" strokeLinecap="round"

View file

@ -2,6 +2,7 @@ import { DocumentMagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { FileComponentType } from "../../types/components"; import { FileComponentType } from "../../types/components";
import { INPUT_STYLE } from "../../constants";
export default function InputFileComponent({ export default function InputFileComponent({
value, value,
@ -37,6 +38,10 @@ export default function InputFileComponent({
return false; return false;
} }
useEffect(() => {
setMyValue(value);
}, [value]);
const handleButtonClick = () => { const handleButtonClick = () => {
const input = document.createElement("input"); const input = document.createElement("input");
input.type = "file"; input.type = "file";
@ -73,8 +78,10 @@ export default function InputFileComponent({
onClick={handleButtonClick} onClick={handleButtonClick}
className={ className={
editNode editNode
? "placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "truncate placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "truncate block w-full text-gray-500 dark:text-gray-300 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "truncate block w-full text-gray-500 dark:text-gray-300 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm sm:text-sm" +
INPUT_STYLE +
(disabled ? " bg-gray-200" : "") (disabled ? " bg-gray-200" : "")
} }
> >
@ -82,7 +89,7 @@ export default function InputFileComponent({
</span> </span>
<button onClick={handleButtonClick}> <button onClick={handleButtonClick}>
{!editNode && ( {!editNode && (
<DocumentMagnifyingGlassIcon className="w-8 h-8 hover:text-blue-600" /> <DocumentMagnifyingGlassIcon className="w-8 h-8 hover:text-ring" />
)} )}
</button> </button>
</div> </div>

View file

@ -4,11 +4,12 @@ import { InputListComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import _ from "lodash"; import _ from "lodash";
import { INPUT_STYLE } from "../../constants";
export default function InputListComponent({ export default function InputListComponent({
value, value,
onChange, onChange,
disabled, disabled,
editNode = false,
}: InputListComponentType) { }: InputListComponentType) {
const [inputList, setInputList] = useState(value ?? [""]); const [inputList, setInputList] = useState(value ?? [""]);
useEffect(() => { useEffect(() => {
@ -21,7 +22,7 @@ export default function InputListComponent({
<div <div
className={ className={
(disabled ? "pointer-events-none cursor-not-allowed" : "") + (disabled ? "pointer-events-none cursor-not-allowed" : "") +
"flex flex-col gap-3" "flex flex-col gap-3 py-2"
} }
> >
{inputList.map((i, idx) => ( {inputList.map((i, idx) => (
@ -30,8 +31,12 @@ export default function InputListComponent({
type="text" type="text"
value={i} value={i}
className={ className={
"block w-full form-input rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + editNode
(disabled ? " bg-gray-200" : "") ? "border-[1px] truncate cursor-pointer text-center placeholder:text-center text-gray-500 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
INPUT_STYLE
: "block w-full form-input rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500 sm:text-sm" +
(disabled ? " bg-gray-200" : "") +
"focus:placeholder-transparent"
} }
placeholder="Type something..." placeholder="Type something..."
onChange={(e) => { onChange={(e) => {
@ -54,7 +59,7 @@ export default function InputListComponent({
onChange(inputList); onChange(inputList);
}} }}
> >
<PlusIcon className="w-4 h-4 hover:text-blue-600" /> <PlusIcon className={"w-4 h-4 hover:text-ring"} />
</button> </button>
) : ( ) : (
<button <button

View file

@ -2,6 +2,7 @@ import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { INPUT_STYLE } from "../../constants";
export default function IntComponent({ export default function IntComponent({
value, value,
@ -12,6 +13,7 @@ export default function IntComponent({
}: FloatComponentType) { }: FloatComponentType) {
const [myValue, setMyValue] = useState(value ?? ""); const [myValue, setMyValue] = useState(value ?? "");
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const min = 0;
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
@ -53,11 +55,20 @@ export default function IntComponent({
} }
}} }}
type="number" type="number"
step="1"
min={min}
onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value < min.toString()) {
e.target.value = min.toString();
}
}}
value={myValue} value={myValue}
className={ className={
editNode editNode
? "text-center arrow-hide placeholder:text-center border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "focus:placeholder-transparent text-center placeholder:text-center border-1 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "block w-full form-input dark:bg-gray-900 arrow-hide dark:border-gray-600 dark:text-gray-300 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "focus:placeholder-transparent block w-full form-input dark:bg-gray-900 dark:border-gray-600 dark:text-gray-300 rounded-md border-gray-300 shadow-sm ring-offset-background sm:text-sm" +
INPUT_STYLE +
(disabled ? " bg-gray-200 dark:bg-gray-700" : "") (disabled ? " bg-gray-200 dark:bg-gray-700" : "")
} }
placeholder={editNode ? "Integer number" : "Type a integer number"} placeholder={editNode ? "Integer number" : "Type a integer number"}

View file

@ -7,7 +7,7 @@ export default function LoadingComponent({ remSize }: LoadingComponentProps) {
<div role="status" className="w-min m-auto"> <div role="status" className="w-min m-auto">
<svg <svg
aria-hidden="true" aria-hidden="true"
className={`w-${remSize} h-${remSize} mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600`} className={`w-${remSize} h-${remSize} mr-2 text-muted animate-spin dark:text-gray-600 fill-blue-600`}
viewBox="0 0 100 101" viewBox="0 0 100 101"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View file

@ -51,7 +51,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
}; };
return ( return (
<div> <>
<Label> <Label>
<div className="flex justify-between"> <div className="flex justify-between">
<span className="font-medium">Name</span>{" "} <span className="font-medium">Name</span>{" "}
@ -84,7 +84,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
rows={3} rows={3}
/> />
</Label> </Label>
</div> </>
); );
}; };

View file

@ -6,6 +6,7 @@ import TextAreaModal from "../../modals/textAreaModal";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TypeModal } from "../../utils"; import { TypeModal } from "../../utils";
import { INPUT_STYLE } from "../../constants";
export default function PromptAreaComponent({ export default function PromptAreaComponent({
value, value,
@ -45,12 +46,13 @@ export default function PromptAreaComponent({
}} }}
className={ className={
editNode editNode
? "h-7 truncate placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "cursor-pointer truncate placeholder:text-center text-gray-500 border-1 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm sm:text-sm" +
(disabled ? " bg-gray-200" : "") (disabled ? " bg-gray-200" : "")
} }
> >
{myValue !== "" ? myValue : "-"} {myValue !== "" ? myValue : "Type your prompt here"}
</span> </span>
<button <button
onClick={() => { onClick={() => {
@ -69,7 +71,7 @@ export default function PromptAreaComponent({
}} }}
> >
{!editNode && ( {!editNode && (
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600 dark:text-gray-300" /> <ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-ring dark:text-gray-300" />
)} )}
</button> </button>
</div> </div>

View file

@ -4,7 +4,7 @@ import { PopUpContext } from "../../contexts/popUpContext";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TypeModal } from "../../utils"; import { TypeModal } from "../../utils";
import { INPUT_STYLE } from "../../constants";
export default function TextAreaComponent({ export default function TextAreaComponent({
value, value,
onChange, onChange,
@ -12,16 +12,28 @@ export default function TextAreaComponent({
editNode = false, editNode = false,
}: TextAreaComponentType) { }: TextAreaComponentType) {
const [myValue, setMyValue] = useState(value); const [myValue, setMyValue] = useState(value);
const { openPopUp } = useContext(PopUpContext); const { openPopUp, closePopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue(""); setMyValue("");
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value);
}, [closePopUp]);
return ( return (
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}> <div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
<div className="w-full flex items-center gap-3"> <div
className={
editNode
? "w-full flex items-center"
: "w-full flex items-center gap-3"
}
>
<span <span
onClick={() => { onClick={() => {
openPopUp( openPopUp(
@ -39,12 +51,13 @@ export default function TextAreaComponent({
}} }}
className={ className={
editNode editNode
? "h-7 truncate placeholder:text-center text-gray-500 border-0 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" ? "truncate cursor-pointer placeholder:text-center text-gray-500 border-1 block w-full pt-0.5 pb-0.5 form-input dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 rounded-md border-gray-300 shadow-sm sm:text-sm" +
: "truncate block w-full text-gray-500 dark:text-gray-100 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + INPUT_STYLE
: "truncate block w-full text-gray-500 dark:text-muted px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm sm:text-sm" +
(disabled ? " bg-gray-200" : "") (disabled ? " bg-gray-200" : "")
} }
> >
{myValue !== "" ? myValue : "Text empty"} {myValue !== "" ? myValue : "Type something..."}
</span> </span>
<button <button
onClick={() => { onClick={() => {
@ -63,7 +76,7 @@ export default function TextAreaComponent({
}} }}
> >
{!editNode && ( {!editNode && (
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600 dark:text-gray-300" /> <ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-ring dark:text-gray-300" />
)} )}
</button> </button>
</div> </div>

View file

@ -21,8 +21,8 @@ export default function ToggleComponent({
setEnabled(x); setEnabled(x);
}} }}
className={classNames( className={classNames(
enabled ? "bg-indigo-600" : "bg-gray-200", enabled ? "bg-primary" : "bg-gray-200",
"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-1 focus:ring-primary focus:ring-offset-1"
)} )}
> >
<span className="sr-only">Use setting</span> <span className="sr-only">Use setting</span>

View file

@ -19,6 +19,7 @@ export default function ToggleShadComponent({
style={{ style={{
transform: "scaleX(0.6) scaleY(0.6)", transform: "scaleX(0.6) scaleY(0.6)",
}} }}
className="data-[state=unchecked]:bg-slate-500"
checked={enabled} checked={enabled}
onCheckedChange={(x: boolean) => { onCheckedChange={(x: boolean) => {
setEnabled(x); setEnabled(x);

View file

@ -4,7 +4,7 @@
* The base text for subtitle of Export Dialog (Toolbar) * The base text for subtitle of Export Dialog (Toolbar)
* @constant * @constant
*/ */
export const EXPORT_DIALOG_SUBTITLE = "Export your models."; export const EXPORT_DIALOG_SUBTITLE = "Export flow as JSON file.";
/** /**
* The base text for subtitle of Flow Settings (Menubar) * The base text for subtitle of Flow Settings (Menubar)
@ -24,25 +24,27 @@ export const CODE_DIALOG_SUBTITLE =
* @constant * @constant
*/ */
export const EDIT_DIALOG_SUBTITLE = export const EDIT_DIALOG_SUBTITLE =
"Make configurations changes to your nodes. Click save when you're done."; "Adjust the configurations of your component. Define parameter visibility for the canvas view. Remember to save once you’re finished.";
/** /**
* The base text for subtitle of Code Dialog * The base text for subtitle of Code Dialog
* @constant * @constant
*/ */
export const CODE_PROMPT_DIALOG_SUBTITLE = "Edit you python code."; export const CODE_PROMPT_DIALOG_SUBTITLE =
"Edit your Python code. This code snippet accepts module import and a single function definition. Make sure that your function returns a string.";
/** /**
* The base text for subtitle of Prompt Dialog * The base text for subtitle of Prompt Dialog
* @constant * @constant
*/ */
export const PROMPT_DIALOG_SUBTITLE = "Edit you prompt."; export const PROMPT_DIALOG_SUBTITLE =
"Create your prompt. Prompts can help guide the behavior of a Language Model.";
/** /**
* The base text for subtitle of Text Dialog * The base text for subtitle of Text Dialog
* @constant * @constant
*/ */
export const TEXT_DIALOG_SUBTITLE = "Edit you text."; export const TEXT_DIALOG_SUBTITLE = "Edit your text.";
/** /**
* Function to get the python code for the API * Function to get the python code for the API
@ -103,3 +105,25 @@ export const getPythonCode = (flowName: string): string => {
# Now you can use it like any chain # Now you can use it like any chain
flow("Hey, have you heard of LangFlow?")`; flow("Hey, have you heard of LangFlow?")`;
}; };
/**
* The base text for subtitle of Import Dialog
* @constant
*/
export const IMPORT_DIALOG_SUBTITLE =
"Upload a JSON file or select from the available community examples.";
/**
* The base text for subtitle of code dialog
* @constant
*/
export const EXPORT_CODE_DIALOG =
"Generate the code to integrate your flow into an external application.";
/**
* The base text for subtitle of code dialog
* @constant
*/
export const INPUT_STYLE =
" focus:ring-1 focus:ring-offset-1 focus:ring-ring focus:outline-none ";

View file

@ -70,16 +70,63 @@
} }
} }
@layer base { :root {
* { --background: 0 0% 100%;
@apply border-border; --foreground: 222.2 47.4% 11.2%;
} --muted: 210 40% 98%;
body { --muted-foreground: 215.4 16.3% 46.9%;
@apply bg-background text-foreground; --popover: 0 0% 100%;
font-feature-settings: "rlig" 1, "calt" 1; --popover-foreground: 222.2 47.4% 11.2%;
} --card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 18%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
.dark {
-background: 224 71% 4%;
-foreground: 213 31% 91%;
-muted: 223 47% 11%;
-muted-foreground: 215.4 16.3% 56.9%;
-popover: 224 71% 4%;
-popover-foreground: 215 20.2% 65.1%;
-card: 224 71% 4%;
-card-foreground: 213 31% 91%;
-border: 216 34% 17%;
-input: 216 34% 17%;
-primary: 210 40% 98%;
-primary-foreground: 222.2 47.4% 1.2%;
-secondary: 222.2 47.4% 11.2%;
-secondary-foreground: 210 40% 98%;
-accent: 216 34% 17%;
-accent-foreground: 210 40% 98%;
-destructive: 0 63% 31%;
-destructive-foreground: 210 40% 98%;
-ring: 216 34% 17%;
-radius: 0.5rem;
}
@layer base {
* {
@apply border-border;
} }
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
body { body {
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
@ -98,4 +145,4 @@ code {
The cursor: default; property value restores the browser's default cursor style for the targeted element. By applying this style, the element will no longer have a custom cursor appearance such as "grab" or any other custom cursor defined elsewhere in the application. Instead, it will revert to the default cursor style determined by the browser, typically an arrow-shaped cursor. */ The cursor: default; property value restores the browser's default cursor style for the targeted element. By applying this style, the element will no longer have a custom cursor appearance such as "grab" or any other custom cursor defined elsewhere in the application. Instead, it will revert to the default cursor style determined by the browser, typically an arrow-shaped cursor. */
.react-flow__pane { .react-flow__pane {
cursor: default; cursor: default;
} }

View file

@ -26,6 +26,7 @@ import {
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { FlowType } from "src/types/flow"; import { FlowType } from "src/types/flow";
import { getCurlCode, getPythonApiCode, getPythonCode } from "../../constants"; import { getCurlCode, getPythonApiCode, getPythonCode } from "../../constants";
import { EXPORT_CODE_DIALOG } from "../../constants";
export default function ApiModal({ flow }: { flow: FlowType }) { export default function ApiModal({ flow }: { flow: FlowType }) {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@ -83,7 +84,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
<DialogTrigger></DialogTrigger> <DialogTrigger></DialogTrigger>
<DialogContent className="lg:max-w-[800px] sm:max-w-[600px] h-[550px]"> <DialogContent className="lg:max-w-[800px] sm:max-w-[600px] h-[580px]">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Code</span> <span className="pr-2">Code</span>
@ -92,9 +93,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </DialogTitle>
<DialogDescription> <DialogDescription>{EXPORT_CODE_DIALOG}</DialogDescription>
Export your flow to use it with this code.
</DialogDescription>
</DialogHeader> </DialogHeader>
<div className="flex flex-col h-full w-full "> <div className="flex flex-col h-full w-full ">
@ -106,18 +105,18 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
setActiveTab(index); setActiveTab(index);
}} }}
className={ className={
"p-2 rounded-t-lg w-44 border border-b-0 border-gray-300 dark:border-gray-700 dark:text-gray-300 -mr-px flex justify-center items-center gap-4 " + "p-1.5 rounded-t-lg w-44 border border-b-0 border-gray-300 dark:border-gray-700 dark:text-gray-300 -mr-px flex justify-center items-center gap-4 " +
(activeTab === index (activeTab === index
? " bg-white dark:bg-gray-800" ? " bg-white dark:bg-gray-800"
: "bg-gray-100 dark:bg-gray-900") : "bg-muted dark:bg-gray-900")
} }
> >
{tab.name} {tab.name}
<img src={tab.image} className="w-6" /> <img src={tab.image} className="w-[23px]" />
</button> </button>
))} ))}
</div> </div>
<div className="overflow-hidden px-4 sm:p-4 sm:pb-0 sm:pt-0 w-full h-full rounded-lg shadow bg-white dark:bg-gray-800"> <div className=" overflow-hidden px-4 sm:p-4 sm:pb-0 sm:pt-0 w-full h-full rounded-lg border-gray-200 border-[1px] bg-muted dark:bg-gray-800">
<div className="items-center mb-2"> <div className="items-center mb-2">
<div className="float-right"> <div className="float-right">
<button <button
@ -134,7 +133,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</div> </div>
</div> </div>
<SyntaxHighlighter <SyntaxHighlighter
className="h-[370px] w-full" className="h-[350px] w-full"
language={tabs[activeTab].mode} language={tabs[activeTab].mode}
style={oneDark} style={oneDark}
customStyle={{ margin: 0 }} customStyle={{ margin: 0 }}

View file

@ -60,12 +60,12 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node.template[t].type === "int") data.node.template[t].type === "int")
).length ).length
); );
const [nodeValue, setNodeValue] = useState(true); const [nodeValue, setNodeValue] = useState(null);
const { closePopUp } = useContext(PopUpContext); const { closePopUp } = useContext(PopUpContext);
const { types } = useContext(typesContext); const { types } = useContext(typesContext);
const ref = useRef(); const ref = useRef();
const { save } = useContext(TabsContext); const { save } = useContext(TabsContext);
const [enabled, setEnabled] = useState(false); const [enabled, setEnabled] = useState(null);
if (nodeLength == 0) { if (nodeLength == 0) {
closePopUp(); closePopUp();
} }
@ -77,6 +77,8 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
} }
} }
useEffect(() => {}, [closePopUp, data.node.template]);
function changeAdvanced(node): void { function changeAdvanced(node): void {
Object.keys(data.node.template).filter((n, i) => { Object.keys(data.node.template).filter((n, i) => {
if (n === node.name) { if (n === node.name) {
@ -87,12 +89,10 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
setNodeValue(!nodeValue); setNodeValue(!nodeValue);
} }
console.log(data.node.template);
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
<DialogTrigger></DialogTrigger> <DialogTrigger></DialogTrigger>
<DialogContent className="lg:max-w-[700px]"> <DialogContent className="lg:max-w-[700px] ">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Edit Node</span> <span className="pr-2">Edit Node</span>
@ -103,21 +103,21 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
</DialogTitle> </DialogTitle>
<DialogDescription> <DialogDescription>
{EDIT_DIALOG_SUBTITLE} {EDIT_DIALOG_SUBTITLE}
<div className="flex pt-3"> <div className="flex pt-4">
<VariableIcon className="w-5 h-5 pe-1 text-gray-700 stroke-2"> <VariableIcon className="w-5 h-5 pe-1 text-gray-700 stroke-2 dark:text-slate-200">
&nbsp; &nbsp;
</VariableIcon> </VariableIcon>
<span className="text-sm font-semibold text-gray-800"> <span className="text-sm font-semibold text-gray-800 dark:text-white">
Parameters Parameters
</span> </span>
</div> </div>
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div className="flex w-full h-fit max-h-[415px]"> <div className="flex w-full max-h-[350px] h-fit">
<div <div
className={classNames( className={classNames(
"w-full rounded-lg bg-white dark:bg-gray-800 shadow", "w-full rounded-lg bg-white dark:bg-gray-800 border-[1px] border-gray-200",
nodeLength > limitScrollFieldsModal nodeLength > limitScrollFieldsModal
? "overflow-scroll overflow-x-hidden custom-scroll" ? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden" : "overflow-hidden"
@ -125,9 +125,9 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
> >
{nodeLength > 0 && ( {nodeLength > 0 && (
<div className="flex flex-col gap-5 h-fit"> <div className="flex flex-col gap-5 h-fit">
<Table className="table-fixed"> <Table className="table-fixed bg-muted outline-1">
<TableHeader className="border-gray-200 text-gray-500 text-xs font-medium"> <TableHeader className="border-gray-200 text-gray-500 text-xs font-medium h-10">
<TableRow> <TableRow className="dark:border-b-muted">
<TableHead className="h-7 text-center">PARAM</TableHead> <TableHead className="h-7 text-center">PARAM</TableHead>
<TableHead className="p-0 h-7 text-center"> <TableHead className="p-0 h-7 text-center">
VALUE VALUE
@ -150,8 +150,8 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node.template[t].type === "int") data.node.template[t].type === "int")
) )
.map((n, i) => ( .map((n, i) => (
<TableRow key={i} className="h-8"> <TableRow key={i} className="h-10 dark:border-b-muted">
<TableCell className="p-0 text-center text-gray-900 text-xs dark:text-gray-300"> <TableCell className="p-0 text-center text-gray-900 text-xs dark:text-gray-300 text-sm">
{data.node.template[n].name {data.node.template[n].name
? data.node.template[n].name ? data.node.template[n].name
: data.node.template[n].display_name} : data.node.template[n].display_name}
@ -162,6 +162,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
<div className="mx-auto"> <div className="mx-auto">
{data.node.template[n].list ? ( {data.node.template[n].list ? (
<InputListComponent <InputListComponent
editNode={true}
disabled={false} disabled={false}
value={ value={
!data.node.template[n].value || !data.node.template[n].value ||
@ -228,6 +229,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node.template[n].options ? ( data.node.template[n].options ? (
<div className="mx-auto"> <div className="mx-auto">
<Dropdown <Dropdown
numberOfOptions={nodeLength}
editNode={true} editNode={true}
options={data.node.template[n].options} options={data.node.template[n].options}
onSelect={(newValue) => onSelect={(newValue) =>

View file

@ -146,7 +146,7 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
<div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4"> <div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4">
<button <button
type="button" type="button"
className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm" className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:ring-offset-1 sm:ml-3 sm:w-auto sm:text-sm"
onClick={() => { onClick={() => {
setModalOpen(false); setModalOpen(false);
}} }}

View file

@ -2,7 +2,7 @@ import { LockClosedIcon, PaperAirplaneIcon } from "@heroicons/react/24/outline";
import { classNames } from "../../../utils"; import { classNames } from "../../../utils";
import { useContext, useEffect, useRef, useState } from "react"; import { useContext, useEffect, useRef, useState } from "react";
import { TabsContext } from "../../../contexts/tabsContext"; import { TabsContext } from "../../../contexts/tabsContext";
import { INPUT_STYLE } from "../../../constants";
export default function ChatInput({ export default function ChatInput({
lockChat, lockChat,
chatValue, chatValue,
@ -46,7 +46,8 @@ export default function ChatInput({
lockChat lockChat
? " bg-gray-300 text-black dark:bg-gray-700 dark:text-gray-300" ? " bg-gray-300 text-black dark:bg-gray-700 dark:text-gray-300"
: " bg-white-200 text-black dark:bg-gray-900 dark:text-gray-300", : " bg-white-200 text-black dark:bg-gray-900 dark:text-gray-300",
"form-input block w-full custom-scroll rounded-md border-gray-300 dark:border-gray-600 pr-10 sm:text-sm" "form-input block w-full custom-scroll rounded-md border-gray-300 dark:border-gray-600 pr-10 sm:text-sm" +
INPUT_STYLE
)} )}
placeholder={"Send a message..."} placeholder={"Send a message..."}
/> />

View file

@ -80,7 +80,7 @@ export default function ChatMessage({
<div <div
onClick={() => setHidden((prev) => !prev)} onClick={() => setHidden((prev) => !prev)}
className=" text-start inline-block rounded-md text-gray-600 dark:text-gray-200 h-full border border-gray-300 dark:border-gray-500 className=" text-start inline-block rounded-md text-gray-600 dark:text-gray-200 h-full border border-gray-300 dark:border-gray-500
bg-gray-100 dark:bg-gray-800 w-[95%] pb-3 pt-3 px-2 ml-3 cursor-pointer scrollbar-hide overflow-scroll" bg-muted dark:bg-gray-800 w-[95%] pb-3 pt-3 px-2 ml-3 cursor-pointer scrollbar-hide overflow-scroll"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: convert.toHtml(chat.thought), __html: convert.toHtml(chat.thought),
}} }}

View file

@ -37,7 +37,7 @@ export default function FileCard({ fileName, content, fileType }) {
/> />
{isHovered && ( {isHovered && (
<div <div
className={`absolute top-0 right-0 bg-gray-100 text-gray-700 rounded-bl-lg px-1 text-sm font-bold dark:bg-gray-700 dark:text-gray-300`} className={`absolute top-0 right-0 bg-muted text-gray-700 rounded-bl-lg px-1 text-sm font-bold dark:bg-gray-700 dark:text-gray-300`}
> >
<button <button
className="text-gray-500 py-1 px-2 dark:bg-gray-700 dark:text-gray-300" className="text-gray-500 py-1 px-2 dark:bg-gray-700 dark:text-gray-300"
@ -54,7 +54,7 @@ export default function FileCard({ fileName, content, fileType }) {
return ( return (
<button <button
onClick={handleDownload} onClick={handleDownload}
className="bg-gray-100 shadow rounded w-1/2 text-gray-700 hover:drop-shadow-lg px-2 py-2 flex justify-between items-center border border-gray-300" className="bg-muted shadow rounded w-1/2 text-gray-700 hover:drop-shadow-lg px-2 py-2 flex justify-between items-center border border-gray-300"
> >
<div className="flex gap-2 text-current items-center w-full mr-2"> <div className="flex gap-2 text-current items-center w-full mr-2">
{" "} {" "}

View file

@ -430,7 +430,7 @@ export default function ChatModal({
</span> </span>
</span> </span>
<br /> <br />
<div className="bg-gray-100 dark:bg-gray-900 rounded-md w-2/4 px-6 py-8 border border-gray-200 dark:border-gray-700"> <div className="bg-muted dark:bg-gray-900 rounded-md w-2/4 px-6 py-8 border border-gray-200 dark:border-gray-700">
<span className="text-base text-gray-500"> <span className="text-base text-gray-500">
Start a conversation and click the agent’s thoughts{" "} Start a conversation and click the agent’s thoughts{" "}
<span> <span>

View file

@ -73,7 +73,7 @@ export default function CodeAreaModal({
onChange={(value) => { onChange={(value) => {
setCode(value); setCode(value);
}} }}
className="w-full rounded-lg h-[300px] custom-scroll" className="w-full rounded-lg h-[300px] custom-scroll border-[1px] border-gray-300 dark:border-gray-600"
/> />
</div> </div>

View file

@ -17,6 +17,9 @@ import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox"; import { Checkbox } from "../../components/ui/checkbox";
import { EXPORT_DIALOG_SUBTITLE } from "../../constants"; import { EXPORT_DIALOG_SUBTITLE } from "../../constants";
import EditFlowSettings from "../../components/nameInputComponent"; import EditFlowSettings from "../../components/nameInputComponent";
import { Label } from "../../components/ui/label";
import { Input } from "../../components/ui/input";
import { Textarea } from "../../components/ui/textarea";
export default function ExportModal() { export default function ExportModal() {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@ -41,7 +44,7 @@ export default function ExportModal() {
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
<DialogTrigger asChild></DialogTrigger> <DialogTrigger asChild></DialogTrigger>
<DialogContent className="lg:max-w-[600px] h-[420px]"> <DialogContent className="lg:max-w-[600px] h-[420px] ">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Export</span> <span className="pr-2">Export</span>
@ -53,16 +56,29 @@ export default function ExportModal() {
<DialogDescription>{EXPORT_DIALOG_SUBTITLE}</DialogDescription> <DialogDescription>{EXPORT_DIALOG_SUBTITLE}</DialogDescription>
</DialogHeader> </DialogHeader>
<EditFlowSettings <Label>
name={name} <span className="font-medium">Name</span>
description={description}
flows={flows} <Input
tabId={tabId} className="mt-2 focus-visible:ring-1"
setName={setName} onChange={(event) => {
setDescription={setDescription} if (event.target.value != "") {
updateFlow={updateFlow} let newFlow = flows.find((f) => f.id === tabId);
/> newFlow.name = event.target.value;
{/* <Label> setName(event.target.value);
updateFlow(newFlow);
} else {
setName(event.target.value);
}
}}
type="text"
name="name"
value={name ?? null}
placeholder="File name"
id="name"
/>
</Label>
<Label>
<span className="font-medium">Description (optional)</span> <span className="font-medium">Description (optional)</span>
<Textarea <Textarea
name="description" name="description"
@ -74,10 +90,10 @@ export default function ExportModal() {
}} }}
value={flows.find((f) => f.id === tabId).description ?? null} value={flows.find((f) => f.id === tabId).description ?? null}
placeholder="Flow description" placeholder="Flow description"
className="max-h-[100px] mt-2" className="max-h-[100px] mt-2 focus-visible:ring-1"
rows={3} rows={3}
/> />
</Label> */} </Label>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox <Checkbox
id="terms" id="terms"

View file

@ -18,7 +18,7 @@ import { Button } from "../../components/ui/button";
import { Textarea } from "../../components/ui/textarea"; import { Textarea } from "../../components/ui/textarea";
import { PROMPT_DIALOG_SUBTITLE, TEXT_DIALOG_SUBTITLE } from "../../constants"; import { PROMPT_DIALOG_SUBTITLE, TEXT_DIALOG_SUBTITLE } from "../../constants";
export default function PromptAreaModal({ export default function GenericModal({
value, value,
setValue, setValue,
buttonText, buttonText,
@ -78,7 +78,7 @@ export default function PromptAreaModal({
<div className="flex h-full w-full mt-2"> <div className="flex h-full w-full mt-2">
<Textarea <Textarea
ref={ref} ref={ref}
className="form-input h-[300px] w-full rounded-lg border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-white" className="form-input h-[300px] w-full rounded-lg border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-white focus-visible:ring-1"
value={myValue} value={myValue}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value); setMyValue(e.target.value);

View file

@ -1,4 +1,3 @@
import { Dialog, Transition } from "@headlessui/react";
import { import {
XMarkIcon, XMarkIcon,
ArrowDownTrayIcon, ArrowDownTrayIcon,
@ -6,6 +5,7 @@ import {
ComputerDesktopIcon, ComputerDesktopIcon,
ArrowUpTrayIcon, ArrowUpTrayIcon,
ArrowLeftIcon, ArrowLeftIcon,
CommandLineIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { Fragment, useContext, useRef, useState } from "react"; import { Fragment, useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext"; import { PopUpContext } from "../../contexts/popUpContext";
@ -17,6 +17,17 @@ import { alertContext } from "../../contexts/alertContext";
import LoadingComponent from "../../components/loadingComponent"; import LoadingComponent from "../../components/loadingComponent";
import { FlowType } from "../../types/flow"; import { FlowType } from "../../types/flow";
import { classNames, snakeToSpaces, toNormalCase } from "../../utils"; import { classNames, snakeToSpaces, toNormalCase } from "../../utils";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { IMPORT_DIALOG_SUBTITLE } from "../../constants";
export default function ImportModal() { export default function ImportModal() {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@ -52,181 +63,143 @@ export default function ImportModal() {
} }
return ( return (
<Transition.Root show={open} appear={true} as={Fragment}> <Dialog open={true} onOpenChange={setModalOpen}>
<Dialog <DialogTrigger></DialogTrigger>
as="div" <DialogContent
className="relative z-10" className={classNames(
onClose={setModalOpen} showExamples
initialFocus={ref} ? "lg:max-w-[650px] h-[600px]"
: "lg:max-w-[650px] h-[450px]"
)}
> >
<Transition.Child <DialogHeader>
as={Fragment} <DialogTitle className="flex items-center">
enter="ease-out duration-300" {showExamples && (
enterFrom="opacity-0" <>
enterTo="opacity-100" <div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block">
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[776px]">
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
<button <button
type="button" type="button"
className="rounded-md text-gray-400 hover:text-gray-500" className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-1 focus:ring-gray-500 focus:ring-offset-1"
onClick={() => { onClick={() => {
setModalOpen(false); setShowExamples(false);
}} }}
> >
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
<XMarkIcon className="h-6 w-6" aria-hidden="true" /> <ArrowLeftIcon
className="h-6 w-6 text-gray-800 ml-1 dark:text-white"
aria-hidden="true"
/>
</button> </button>
</div> </div>
{showExamples && ( </>
<> )}
<div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block">
<button <span className={classNames(showExamples ? "pl-8 pr-2" : "pr-2")}>
type="button" {showExamples ? "Select an example" : "Import"}
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" </span>
onClick={() => { <ArrowUpTrayIcon
setShowExamples(false); className="h-6 w-6 text-gray-800 ml-1 dark:text-white"
}} aria-hidden="true"
> />
<span className="sr-only">Close</span> </DialogTitle>
<ArrowLeftIcon className="h-6 w-6" aria-hidden="true" /> <DialogDescription>{IMPORT_DIALOG_SUBTITLE}</DialogDescription>
</button> </DialogHeader>
</div>
</> <div
)} className={classNames(
<div className="h-full w-full flex flex-col justify-center items-center"> "h-full w-full dark:bg-gray-900 overflow-y-auto scrollbar-hide",
<div className="flex w-full pb-4 z-10 justify-center shadow-sm"> showExamples && !loadingExamples
<div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10"> ? "flex flex-row start justify-center items-start flex-wrap overflow-auto mx-auto"
<ArrowUpTrayIcon : "flex flex-row justify-center items-center"
className="h-6 w-6 text-blue-600" )}
aria-hidden="true" >
/> {!showExamples && (
</div> <div className="flex h-full w-full justify-evenly items-center">
<div className="mt-4 text-center sm:ml-4 sm:text-left"> <ButtonBox
<Dialog.Title size="big"
as="h3" bgColor="bg-emerald-500 dark:bg-emerald-500/75"
className="text-lg font-medium dark:text-white leading-10 text-gray-900" description="Prebuilt Examples"
> icon={
{showExamples ? "Select an example" : "Import"} <DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" />
</Dialog.Title> }
</div> onClick={() => {
</div> setShowExamples(true);
<div handleExamples();
className={classNames( }}
"h-full w-full bg-gray-200 dark:bg-gray-900 gap-4 overflow-y-auto scrollbar-hide", textColor="text-emerald-500 dark:text-emerald-500/75"
showExamples && !loadingExamples title="Examples"
? "flex flex-row start justify-start items-start p-9 flex-wrap overflow-auto" ></ButtonBox>
: "flex flex-row justify-center items-center p-4" <ButtonBox
)} size="big"
> bgColor="bg-blue-500 dark:bg-blue-500/75"
{!showExamples && ( description="Import from Local"
<div className="flex h-full w-full justify-evenly items-center"> icon={
<ButtonBox <ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" />
size="big" }
bgColor="bg-emerald-500 dark:bg-emerald-500/75" onClick={() => {
description="Prebuilt Examples" uploadFlow();
icon={ setModalOpen(false);
<DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" /> }}
} textColor="text-blue-500 dark:text-blue-500/75"
onClick={() => { title="Local File"
setShowExamples(true); ></ButtonBox>
handleExamples(); </div>
}} )}
textColor="text-emerald-500 dark:text-emerald-500/75" {showExamples && loadingExamples && (
title="Examples" <div className="flex align-middle justify-center items-center">
></ButtonBox> <LoadingComponent remSize={30} />
<ButtonBox </div>
size="big" )}
bgColor="bg-blue-500 dark:bg-blue-500/75" {showExamples &&
description="Import from Local" !loadingExamples &&
icon={ examples.map((example, index) => {
<ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" /> return (
} <div key={example.name} className="m-2">
onClick={() => { {" "}
uploadFlow(false); <ButtonBox
setModalOpen(false); size="small"
}} bgColor="bg-emerald-500 dark:bg-emerald-500/75"
textColor="text-blue-500 dark:text-blue-500/75" description={example.description ?? "Prebuilt Examples"}
title="Local File" icon={
></ButtonBox> <DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" />
</div> }
)} onClick={() => {
{showExamples && loadingExamples && ( addFlow(example, false);
<div className="flex align-middle justify-center items-center"> setModalOpen(false);
<LoadingComponent remSize={30} /> }}
</div> textColor="text-emerald-500 dark:text-emerald-500/75"
)} title={example.name}
{showExamples && ></ButtonBox>
!loadingExamples &&
examples.map((example, index) => {
return (
<div key={index}>
{" "}
<ButtonBox
size="small"
bgColor="bg-emerald-500 dark:bg-emerald-500/75"
description={
example.description ?? "Prebuilt Examples"
}
icon={
<DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" />
}
onClick={() => {
addFlow(example, false);
setModalOpen(false);
}}
textColor="text-emerald-500 dark:text-emerald-500/75"
title={example.name}
></ButtonBox>
</div>
);
})}
</div>
<div className="bg-white dark:bg-gray-800 w-full h-20 flex items-center justify-center">
<a
href="https://github.com/logspace-ai/langflow_examples"
target="_blank"
className="flex items-center justify-center text-gray-600 dark:text-gray-300"
rel="noreferrer"
>
<svg
width="24"
viewBox="0 0 98 96"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
fill="currentColor"
/>
</svg>
<span className="ml-2 ">LangFlow Examples</span>
</a>
</div>
</div> </div>
</Dialog.Panel> );
</Transition.Child> })}
</div>
</div> </div>
</Dialog>
</Transition.Root> <DialogFooter>
<div className="w-full flex items-center justify-center mt-2">
<a
href="https://github.com/logspace-ai/langflow_examples"
target="_blank"
className="flex items-center justify-center text-gray-600 dark:text-gray-300"
rel="noreferrer"
>
<svg
width="24"
viewBox="0 0 98 96"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
fill="currentColor"
/>
</svg>
<span className="ml-2 ">LangFlow Examples</span>
</a>
</div>
</DialogFooter>
</DialogContent>
</Dialog>
); );
} }

View file

@ -105,7 +105,7 @@ export default function PromptAreaModal({
<div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4"> <div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4">
<button <button
type="button" type="button"
className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm" className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-ring focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:ring-offset-1 sm:ml-3 sm:w-auto sm:text-sm"
onClick={() => { onClick={() => {
checkPrompt(myValue) checkPrompt(myValue)
.then((apiReturn) => { .then((apiReturn) => {

View file

@ -104,7 +104,7 @@ export default function TextAreaModal({
<div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4"> <div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4">
<button <button
type="button" type="button"
className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm" className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:ring-offset-1 sm:ml-3 sm:w-auto sm:text-sm"
onClick={() => { onClick={() => {
setModalOpen(false); setModalOpen(false);
}} }}

View file

@ -1,70 +0,0 @@
import { GitFork } from "lucide-react";
import { useContext } from "react";
import { useNavigate } from "react-router-dom";
import { TabsContext } from "../../../../contexts/tabsContext";
import { FlowType } from "../../../../types/flow";
import { gradients } from "../../../../utils";
import {
CardTitle,
CardDescription,
CardFooter,
Card,
CardHeader,
} from "../../../../components/ui/card";
import { Button } from "../../../../components/ui/button";
export const CardComponent = ({ flow, id }: { flow: FlowType; id: string }) => {
const { addFlow } = useContext(TabsContext);
const navigate = useNavigate();
return (
<Card className="group">
<CardHeader>
<CardTitle className="flex justify-between items-start">
<div className="flex gap-4 items-center">
<span
className={
"rounded-full w-8 h-8 flex items-center justify-center text-2xl " +
gradients[parseInt(flow.id.slice(0, 6), 16) % gradients.length]
}
></span>
<span className="flex-1 truncate-doubleline">{flow.name}</span>
</div>
</CardTitle>
<CardDescription className="pt-2 pb-2">
<div className="truncate-doubleline">
{flow.description}
{/* {flow.description} */}
</div>
</CardDescription>
</CardHeader>
<CardFooter>
<div className="flex gap-2 w-full justify-between items-end">
<div className="flex flex-wrap gap-2">
{/* <Badge variant="secondary">Agent</Badge>
<Badge variant="secondary">
<div className="w-3">
<OpenAiIcon />
</div>
<span className="text-base">&nbsp;</span>OpenAI+
</Badge> */}
</div>
<Button
variant="outline"
size="sm"
className="whitespace-nowrap "
onClick={() => {
addFlow(flow, true).then((id) => {
navigate("/flow/" + id);
});
}}
>
<GitFork className="w-4 mr-2" />
Fork Example
</Button>
</div>
</CardFooter>
</Card>
);
};

View file

@ -18,6 +18,7 @@ import {
Plus, Plus,
Home, Home,
Users2, Users2,
GitFork,
} from "lucide-react"; } from "lucide-react";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import AlertDropdown from "../../alerts/alertDropDown"; import AlertDropdown from "../../alerts/alertDropDown";
@ -37,7 +38,8 @@ import {
} from "../../controllers/API"; } from "../../controllers/API";
import { MenuBar } from "../../components/headerComponent/components/menuBar"; import { MenuBar } from "../../components/headerComponent/components/menuBar";
import { FlowType } from "../../types/flow"; import { FlowType } from "../../types/flow";
import { CardComponent } from "./components/cardComponent"; import { CardComponent } from "../../components/cardComponent";
import { useNavigate } from "react-router-dom";
export default function CommunityPage() { export default function CommunityPage() {
const { flows, setTabId, downloadFlows, uploadFlows, addFlow } = const { flows, setTabId, downloadFlows, uploadFlows, addFlow } =
useContext(TabsContext); useContext(TabsContext);
@ -61,6 +63,7 @@ export default function CommunityPage() {
}) })
); );
} }
const navigate = useNavigate();
useEffect(() => { useEffect(() => {
handleExamples(); handleExamples();
@ -87,7 +90,19 @@ export default function CommunityPage() {
<div className="w-full p-4 grid gap-4 md:grid-cols-2 lg:grid-cols-4"> <div className="w-full p-4 grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{!loadingExamples && {!loadingExamples &&
examples.map((flow, idx) => ( examples.map((flow, idx) => (
<CardComponent key={idx} flow={flow} id={flow.id} /> <CardComponent key={idx} flow={flow} id={flow.id} button={<Button
variant="outline"
size="sm"
className="whitespace-nowrap "
onClick={() => {
addFlow(flow, true).then((id) => {
navigate("/flow/" + id);
});
}}
>
<GitFork className="w-4 mr-2" />
Fork Example
</Button>}/>
))} ))}
</div> </div>
</div> </div>

View file

@ -12,7 +12,7 @@ export default function DisclosureComponent({
{({ open }) => ( {({ open }) => (
<> <>
<div> <div>
<Disclosure.Button className="select-none bg-gray-50 dark:bg-gray-700/60 dark:border-y-gray-600 w-full flex justify-between items-center -mt-px px-3 py-2 border-y border-y-gray-200"> <Disclosure.Button className="select-none bg-muted dark:bg-gray-700/60 dark:border-y-gray-600 w-full flex justify-between items-center -mt-px px-3 py-2 border-y border-y-gray-200">
<div className="flex gap-4"> <div className="flex gap-4">
<Icon className="w-6 text-gray-800 dark:text-white/80" /> <Icon className="w-6 text-gray-800 dark:text-white/80" />
<span className="flex items-center text-sm text-gray-800 dark:text-white/80 font-medium"> <span className="flex items-center text-sm text-gray-800 dark:text-white/80 font-medium">

View file

@ -25,6 +25,7 @@ import { TabsContext } from "../../../../contexts/tabsContext";
import { Separator } from "../../../../components/ui/separator"; import { Separator } from "../../../../components/ui/separator";
import { alertContext } from "../../../../contexts/alertContext"; import { alertContext } from "../../../../contexts/alertContext";
import { updateFlowInDatabase } from "../../../../controllers/API"; import { updateFlowInDatabase } from "../../../../controllers/API";
import { INPUT_STYLE } from "../../../../constants";
export default function ExtraSidebar() { export default function ExtraSidebar() {
const { data } = useContext(typesContext); const { data } = useContext(typesContext);
@ -132,7 +133,10 @@ export default function ExtraSidebar() {
name="search" name="search"
id="search" id="search"
placeholder="Search nodes" placeholder="Search nodes"
className="dark:text-white focus:outline-none block w-full rounded-md py-1.5 ps-3 pr-9 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 sm:text-sm sm:leading-6 dark:ring-0 dark:bg-[#2d3747] dark:focus:outline-none" className={
INPUT_STYLE +
"border-1 dark:border-slate-600 dark:border-0.5 dark:ring-0 focus-visible:dark:ring-0 focus-visible:dark:ring-offset-1 rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
}
onChange={(e) => { onChange={(e) => {
handleSearchInput(e.target.value); handleSearchInput(e.target.value);
setSearch(e.target.value); setSearch(e.target.value);

View file

@ -43,7 +43,7 @@ const NodeToolbarComponent = (props) => {
<span className="isolate inline-flex rounded-md shadow-sm"> <span className="isolate inline-flex rounded-md shadow-sm">
<ShadTooltip delayDuration={1000} content="Delete" side="top"> <ShadTooltip delayDuration={1000} content="Delete" side="top">
<button <button
className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative inline-flex items-center rounded-l-md bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10" className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative inline-flex items-center rounded-l-md bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10"
onClick={() => { onClick={() => {
props.deleteNode(props.data.id); props.deleteNode(props.data.id);
}} }}
@ -56,8 +56,8 @@ const NodeToolbarComponent = (props) => {
<button <button
className={classNames( className={classNames(
nodeLength > 0 nodeLength > 0
? "hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10" ? "hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10"
: "hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10 rounded-r-md" : "hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10 rounded-r-md"
)} )}
onClick={(event) => { onClick={(event) => {
event.preventDefault(); event.preventDefault();
@ -83,7 +83,7 @@ const NodeToolbarComponent = (props) => {
{nodeLength > 0 && ( {nodeLength > 0 && (
<ShadTooltip delayDuration={1000} content="Edit" side="top"> <ShadTooltip delayDuration={1000} content="Edit" side="top">
<button <button
className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10 rounded-r-md" className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10 rounded-r-md"
onClick={(event) => { onClick={(event) => {
event.preventDefault(); event.preventDefault();
props.openPopUp(<EditNodeModal data={props.data} />); props.openPopUp(<EditNodeModal data={props.data} />);
@ -96,7 +96,7 @@ const NodeToolbarComponent = (props) => {
{/* {/*
<Menu as="div" className="relative inline-block text-left z-100"> <Menu as="div" className="relative inline-block text-left z-100">
<button className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10 rounded-r-md"> <button className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10 rounded-r-md">
<div> <div>
<Menu.Button className="flex items-center"> <Menu.Button className="flex items-center">
<EllipsisVerticalIcon <EllipsisVerticalIcon
@ -128,7 +128,7 @@ const NodeToolbarComponent = (props) => {
}} }}
className={classNames( className={classNames(
active active
? "bg-gray-100 text-gray-900" ? "bg-muted text-gray-900"
: "text-gray-700", : "text-gray-700",
"w-full group flex items-center px-4 py-2 text-sm" "w-full group flex items-center px-4 py-2 text-sm"
)} )}
@ -168,7 +168,7 @@ const NodeToolbarComponent = (props) => {
}} }}
className={classNames( className={classNames(
active active
? "bg-gray-100 text-gray-900" ? "bg-muted text-gray-900"
: "text-gray-700", : "text-gray-700",
"w-full group flex items-center px-4 py-2 text-sm" "w-full group flex items-center px-4 py-2 text-sm"
)} )}

View file

@ -1,11 +1,11 @@
import { useContext, useEffect } from "react"; import { useContext, useEffect } from "react";
import { Download, Upload, Plus, Home } from "lucide-react"; import { Download, Upload, Plus, Home, ExternalLink } from "lucide-react";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { CardComponent } from "./components/cardComponent"; import { Link, useNavigate } from "react-router-dom";
import { useNavigate } from "react-router-dom"; import { CardComponent } from "../../components/cardComponent";
export default function HomePage() { export default function HomePage() {
const { flows, setTabId, downloadFlows, uploadFlows, addFlow } = const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } =
useContext(TabsContext); useContext(TabsContext);
useEffect(() => { useEffect(() => {
setTabId(""); setTabId("");
@ -50,13 +50,32 @@ export default function HomePage() {
</Button> </Button>
</div> </div>
</div> </div>
<span className="flex pb-8 px-6 text-muted-foreground w-[60%]"> <span className="flex pb-14 px-6 text-muted-foreground w-[60%]">
Manage your personal projects. Download or upload your complete project Manage your personal projects. Download or upload your complete project
collection. collection.
</span> </span>
<div className="w-full p-4 grid gap-4 md:grid-cols-2 lg:grid-cols-4"> <div className="w-full p-4 grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{flows.map((flow, idx) => ( {flows.map((flow, idx) => (
<CardComponent key={idx} flow={flow} id={flow.id} /> <CardComponent
key={idx}
flow={flow}
id={flow.id}
button={
<Link to={"/flow/" + flow.id}>
<Button
variant="outline"
size="sm"
className="whitespace-nowrap "
>
<ExternalLink className="w-4 mr-2" />
Edit Flow
</Button>
</Link>
}
onDelete={() => {
removeFlow(flow.id);
}}
/>
))} ))}
</div> </div>
</div> </div>

View file

@ -13,6 +13,8 @@ export type InputComponentType = {
password: boolean; password: boolean;
disableCopyPaste?: boolean; disableCopyPaste?: boolean;
editNode?: boolean; editNode?: boolean;
onChangePass?: (value: boolean | boolean) => void;
showPass?: boolean;
}; };
export type ToggleComponentType = { export type ToggleComponentType = {
enabled: boolean; enabled: boolean;
@ -24,6 +26,7 @@ export type DropDownComponentType = {
options: string[]; options: string[];
onSelect: (value: string) => void; onSelect: (value: string) => void;
editNode?: boolean; editNode?: boolean;
numberOfOptions?: number;
}; };
export type ParameterComponentType = { export type ParameterComponentType = {
data: NodeDataType; data: NodeDataType;
@ -40,6 +43,7 @@ export type InputListComponentType = {
value: string[]; value: string[];
onChange: (value: string[]) => void; onChange: (value: string[]) => void;
disabled: boolean; disabled: boolean;
editNode?: boolean;
}; };
export type TextAreaComponentType = { export type TextAreaComponentType = {

View file

@ -55,7 +55,7 @@ export function classNames(...classes: Array<string>) {
return classes.filter(Boolean).join(" "); return classes.filter(Boolean).join(" ");
} }
export const limitScrollFieldsModal = 7; export const limitScrollFieldsModal = 10;
export enum TypeModal { export enum TypeModal {
TEXT = 1, TEXT = 1,