Refactored just logic of IOView
This commit is contained in:
parent
dde6fd6d62
commit
d192b50f76
3 changed files with 105 additions and 121 deletions
|
|
@ -1,9 +1,7 @@
|
||||||
import { ReactNode, useState } from "react";
|
import { useState } from "react";
|
||||||
import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants";
|
import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||||
import BaseModal from "../../modals/baseModal";
|
import BaseModal from "../../modals/baseModal";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import { NodeType } from "../../types/flow";
|
|
||||||
import { isInputType, isOutputType } from "../../utils/reactflowUtils";
|
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
import AccordionComponent from "../AccordionComponent";
|
import AccordionComponent from "../AccordionComponent";
|
||||||
import IOInputField from "../IOInputField";
|
import IOInputField from "../IOInputField";
|
||||||
|
|
@ -14,60 +12,32 @@ import { Badge } from "../ui/badge";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
|
|
||||||
export default function IOView({ children, open, setOpen }): JSX.Element {
|
export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
const inputs = useFlowStore((state) => state.inputs);
|
const inputs = useFlowStore((state) => state.inputs).filter(
|
||||||
const outputs = useFlowStore((state) => state.outputs);
|
(input) => input.type !== "ChatInput"
|
||||||
const inputIds = inputs.map((obj) => obj.id);
|
);
|
||||||
const outputIds = outputs.map((obj) => obj.id);
|
const outputs = useFlowStore((state) => state.outputs).filter(
|
||||||
const nodes = useFlowStore((state) => state.nodes);
|
(output) => output.type !== "ChatOutput"
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
);
|
||||||
const categories = getCategories();
|
const nodes = useFlowStore((state) => state.nodes).filter(
|
||||||
const [selectedCategory, setSelectedCategory] = useState<number>(0);
|
(node) =>
|
||||||
const [showChat, setShowChat] = useState<boolean>(false);
|
(inputs.some((input) => input.id === node.id) ||
|
||||||
const [selectedView, setSelectedView] = useState<{
|
outputs.some((output) => output.id === node.id)) &&
|
||||||
type: string;
|
node.type !== "ChatInput" &&
|
||||||
id?: string;
|
node.type !== "ChatOutput"
|
||||||
}>(handleInitialView());
|
);
|
||||||
|
const haveChat = useFlowStore((state) => state.outputs).some(
|
||||||
type CategoriesType = { name: string; icon: string };
|
(output) => output.type === "ChatOutput"
|
||||||
|
);
|
||||||
function handleInitialView() {
|
const [selectedTab, setSelectedTab] = useState(
|
||||||
if (
|
inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0
|
||||||
outputs.map((output) => output.type).includes("ChatOutput") ||
|
);
|
||||||
inputs.map((input) => input.type).includes("ChatInput")
|
const [selectedViewField, setSelectedViewField] = useState<
|
||||||
) {
|
{ type: string; id: string } | undefined
|
||||||
return { type: "ChatOutput" };
|
>(undefined);
|
||||||
}
|
|
||||||
return { type: "" };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCategories() {
|
|
||||||
const categories: CategoriesType[] = [];
|
|
||||||
if (inputs.filter((input) => input.type !== "ChatInput").length > 0)
|
|
||||||
categories.push({ name: "Inputs", icon: "TextCursorInput" });
|
|
||||||
if (outputs.filter((output) => output.type !== "ChatOutput").length > 0)
|
|
||||||
categories.push({ name: "Outputs", icon: "TerminalSquare" });
|
|
||||||
return categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSelectChange(): ReactNode {
|
|
||||||
const { type, id } = selectedView;
|
|
||||||
if (type === "ChatOutput") return <NewChatView />;
|
|
||||||
if (isInputType(type))
|
|
||||||
return <IOInputField inputId={id!} inputType={type} />;
|
|
||||||
if (isOutputType(type))
|
|
||||||
return <IOOutputView outputId={id!} outputType={type} />;
|
|
||||||
else return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function UpdateAccordion() {
|
|
||||||
return (categories[selectedCategory]?.name ?? "Inputs") === "Inputs"
|
|
||||||
? inputs
|
|
||||||
: outputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal
|
<BaseModal
|
||||||
size={handleSelectChange() ? "large" : "small"}
|
size={haveChat ? "large" : "small"}
|
||||||
open={open}
|
open={open}
|
||||||
setOpen={setOpen}
|
setOpen={setOpen}
|
||||||
>
|
>
|
||||||
|
|
@ -88,71 +58,72 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"mr-6 flex h-full w-2/6 flex-col justify-start overflow-auto scrollbar-hide",
|
"mr-6 flex h-full w-2/6 flex-col justify-start overflow-auto scrollbar-hide",
|
||||||
handleSelectChange() ? "w-2/6" : "w-full"
|
haveChat ? "w-2/6" : "w-full"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between py-2">
|
<div className="flex w-full items-center justify-between py-2">
|
||||||
<div className="flex items-start gap-4">
|
<div className="flex items-start gap-4">
|
||||||
{categories.map((category, index) => {
|
|
||||||
return (
|
|
||||||
//hide chat button if chat is alredy on the view
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setSelectedCategory(index)}
|
onClick={() => setSelectedTab(1)}
|
||||||
variant={
|
variant={selectedTab === 1 ? "primary" : "secondary"}
|
||||||
index === selectedCategory ? "primary" : "secondary"
|
|
||||||
}
|
|
||||||
key={index}
|
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name={category.icon}
|
name="FormInput"
|
||||||
className=" file-component-variable"
|
className=" file-component-variable"
|
||||||
/>
|
/>
|
||||||
<span className="file-component-variables-span text-md">
|
<span className="file-component-variables-span text-md">
|
||||||
{category.name}
|
Inputs
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
{(outputs.map((output) => output.type).includes("ChatOutput") ||
|
|
||||||
inputs.map((output) => output.type).includes("chatInput")) &&
|
|
||||||
selectedView.type !== "ChatOutput" && (
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setSelectedView({ type: "ChatOutput" })}
|
onClick={() => setSelectedTab(2)}
|
||||||
|
variant={selectedTab === 2 ? "primary" : "secondary"}
|
||||||
|
>
|
||||||
|
<IconComponent
|
||||||
|
name="ChevronRightSquare"
|
||||||
|
className=" file-component-variable"
|
||||||
|
/>
|
||||||
|
<span className="file-component-variables-span text-md">
|
||||||
|
Outputs
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{selectedViewField && haveChat && (
|
||||||
|
<Button
|
||||||
|
onClick={() => setSelectedViewField(undefined)}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
key={"chat"}
|
key={"chat"}
|
||||||
className="self-end px-2.5"
|
className="self-end px-2.5"
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent name="MessageSquareMore" className="h-5 w-5" />
|
||||||
name="MessageSquareMore"
|
|
||||||
className="h-5 w-5"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-2 mb-2 mt-4 flex items-center gap-2 font-semibold">
|
<div className="mx-2 mb-2 mt-4 flex items-center gap-2 font-semibold">
|
||||||
{categories[selectedCategory]?.name === "Inputs" && (
|
{selectedTab === 1 && (
|
||||||
<>
|
<>
|
||||||
<IconComponent name={"FormInput"} />
|
<IconComponent name={"FormInput"} />
|
||||||
Text Inputs
|
Text Inputs
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{categories[selectedCategory]?.name === "Outputs" && (
|
{selectedTab === 2 && (
|
||||||
<>
|
<>
|
||||||
<IconComponent name={"ChevronRightSquare"} />
|
<IconComponent name={"ChevronRightSquare"} />
|
||||||
Prompt Outputs
|
Prompt Outputs
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{UpdateAccordion()
|
{nodes
|
||||||
.filter(
|
.filter((node) =>
|
||||||
(input) =>
|
selectedTab === 1
|
||||||
input.type !== "ChatInput" && input.type !== "ChatOutput"
|
? inputs.some((input) => input.id === node.id)
|
||||||
|
: outputs.some((output) => output.id === node.id)
|
||||||
)
|
)
|
||||||
.map((input, index) => {
|
.map((node, index) => {
|
||||||
const node: NodeType = nodes.find(
|
const input =
|
||||||
(node) => node.id === input.id
|
selectedTab === 1
|
||||||
)!;
|
? inputs.find((input) => input.id === node.id)!
|
||||||
|
: outputs.find((output) => output.id === node.id)!;
|
||||||
return (
|
return (
|
||||||
<div className="file-component-accordion-div" key={index}>
|
<div className="file-component-accordion-div" key={index}>
|
||||||
<AccordionComponent
|
<AccordionComponent
|
||||||
|
|
@ -161,14 +132,12 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
<Badge variant="gray" size="md">
|
<Badge variant="gray" size="md">
|
||||||
{input.id}
|
{input.id}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
{haveChat && (
|
||||||
<div
|
<div
|
||||||
className="-mb-1 pr-4"
|
className="-mb-1 pr-4"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
setSelectedView({
|
setSelectedViewField(input);
|
||||||
type: input.type,
|
|
||||||
id: input.id,
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
|
|
@ -176,6 +145,7 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
name="ExternalLink"
|
name="ExternalLink"
|
||||||
></IconComponent>
|
></IconComponent>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -183,8 +153,8 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
>
|
>
|
||||||
<div className="file-component-tab-column">
|
<div className="file-component-tab-column">
|
||||||
<div className="">
|
<div className="">
|
||||||
{node &&
|
{input &&
|
||||||
(categories[selectedCategory]?.name === "Inputs" ? (
|
(selectedTab === 1 ? (
|
||||||
<IOInputField
|
<IOInputField
|
||||||
inputType={input.type}
|
inputType={input.type}
|
||||||
inputId={input.id}
|
inputId={input.id}
|
||||||
|
|
@ -202,8 +172,22 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
{handleSelectChange() ? (
|
{haveChat ? (
|
||||||
handleSelectChange()
|
selectedViewField ? (
|
||||||
|
inputs.some((input) => input.id === selectedViewField.id) ? (
|
||||||
|
<IOInputField
|
||||||
|
inputType={selectedViewField.type!}
|
||||||
|
inputId={selectedViewField.id!}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<IOOutputView
|
||||||
|
outputType={selectedViewField.type!}
|
||||||
|
outputId={selectedViewField.id!}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<NewChatView />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<div className="absolute bottom-8 right-8">
|
<div className="absolute bottom-8 right-8">
|
||||||
<Button className="px-3">
|
<Button className="px-3">
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import { classNames } from "../../utils/utils";
|
||||||
import ChatInput from "./chatInput";
|
import ChatInput from "./chatInput";
|
||||||
import ChatMessage from "./chatMessage";
|
import ChatMessage from "./chatMessage";
|
||||||
|
|
||||||
export default function newChatView(): JSX.Element {
|
export default function NewChatView(): JSX.Element {
|
||||||
const [chatValue, setChatValue] = useState("");
|
const [chatValue, setChatValue] = useState("");
|
||||||
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
|
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
|
|
@ -681,4 +681,4 @@ export const LANGFLOW_SUPPORTED_TYPES = new Set([
|
||||||
export const priorityFields = new Set(["code", "template"]);
|
export const priorityFields = new Set(["code", "template"]);
|
||||||
|
|
||||||
export const INPUT_TYPES = new Set(["ChatInput", "TextInput"]);
|
export const INPUT_TYPES = new Set(["ChatInput", "TextInput"]);
|
||||||
export const OUTPUT_TYPES = new Set(["ChatOutput"]);
|
export const OUTPUT_TYPES = new Set(["ChatOutput", "PromptTemplate"]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue