diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/components/sessionSelector/newSessionSelector.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/components/sessionSelector/newSessionSelector.tsx
index f6de50d7b..40fecf1c5 100644
--- a/src/frontend/src/modals/IOModal/components/IOFieldView/components/sessionSelector/newSessionSelector.tsx
+++ b/src/frontend/src/modals/IOModal/components/IOFieldView/components/sessionSelector/newSessionSelector.tsx
@@ -1,6 +1,5 @@
import IconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
-import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
Select,
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/contentView/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/contentView/index.tsx
new file mode 100644
index 000000000..c819fd891
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/contentView/index.tsx
@@ -0,0 +1,197 @@
+import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
+import { TextShimmer } from "@/components/ui/TextShimmer";
+import { cn } from "@/utils/utils";
+import { AnimatePresence, motion } from "framer-motion";
+import Markdown from "react-markdown";
+import remarkGfm from "remark-gfm";
+import CodeTabsComponent from "../../../../../../../components/core/codeTabsComponent/ChatCodeTabComponent";
+import LogoIcon from "../chatLogoIcon";
+
+export const ErrorView = ({
+ closeChat,
+ fitViewNode,
+ chat,
+ showError,
+ lastMessage,
+ blocks,
+}: {
+ blocks: any;
+ showError: boolean;
+ lastMessage: boolean;
+ closeChat?: () => void;
+ fitViewNode: (id: string) => void;
+ chat: any;
+}) => {
+ return (
+ <>
+
+
+ {!showError && lastMessage ? (
+
+
+
+
+ Flow running...
+
+
+
+ ) : (
+
+
+ {blocks.map((block, blockIndex) => (
+
+ {block.contents.map((content, contentIndex) => {
+ if (content.type === "error") {
+ return (
+
+
+
+ {content.component && (
+ <>
+
+ An error occured in the{" "}
+ {
+ fitViewNode(
+ chat.properties?.source?.id ?? "",
+ );
+ closeChat?.();
+ }}
+ >
+ {content.component}
+ {" "}
+ Component, stopping your flow. See below for
+ more details.
+
+ >
+ )}
+
+
+
+ Error details:
+
+ {content.field && (
+
Field: {content.field}
+ )}
+ {content.reason && (
+
+ (
+
+ {props.children}
+
+ ),
+ p({ node, ...props }) {
+ return (
+
+ {props.children}
+
+ );
+ },
+ code: ({
+ node,
+ inline,
+ className,
+ children,
+ ...props
+ }) => {
+ let content = children as string;
+ if (
+ Array.isArray(children) &&
+ children.length === 1 &&
+ typeof children[0] === "string"
+ ) {
+ content = children[0] as string;
+ }
+ if (typeof content === "string") {
+ if (content.length) {
+ if (content[0] === "▍") {
+ return (
+
+ );
+ }
+ }
+
+ const match = /language-(\w+)/.exec(
+ className || "",
+ );
+
+ return !inline ? (
+
+ ) : (
+
+ {content}
+
+ );
+ }
+ },
+ }}
+ >
+ {content.reason}
+
+
+ )}
+ {content.solution && (
+
+
+ Steps to fix:
+
+
+ - Check the component settings
+ - Ensure all required fields are filled
+ - Re-run your flow
+
+
+ )}
+
+
+ );
+ }
+ return null;
+ })}
+
+ ))}
+
+ )}
+
+
+ >
+ );
+};
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/editMessage/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/editMessage/index.tsx
new file mode 100644
index 000000000..6dff003ca
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/components/editMessage/index.tsx
@@ -0,0 +1,83 @@
+import { cn } from "@/utils/utils";
+
+import { EMPTY_OUTPUT_SEND_MESSAGE } from "@/constants/constants";
+import Markdown from "react-markdown";
+import rehypeMathjax from "rehype-mathjax";
+import remarkGfm from "remark-gfm";
+import CodeTabsComponent from "../../../../../../../components/core/codeTabsComponent/ChatCodeTabComponent";
+import EditMessageField from "../editMessageField";
+
+type MarkdownFieldProps = {
+ chat: any;
+ isEmpty: boolean;
+ chatMessage: string;
+ editedFlag: React.ReactNode;
+};
+
+export const MarkdownField = ({
+ chat,
+ isEmpty,
+ chatMessage,
+ editedFlag,
+}: MarkdownFieldProps) => {
+ return (
+
+
{props.children};
+ },
+ ol({ node, ...props }) {
+ return {props.children}
;
+ },
+ ul({ node, ...props }) {
+ return ;
+ },
+ pre({ node, ...props }) {
+ return <>{props.children}>;
+ },
+ code: ({ node, inline, className, children, ...props }) => {
+ let content = children as string;
+ if (
+ Array.isArray(children) &&
+ children.length === 1 &&
+ typeof children[0] === "string"
+ ) {
+ content = children[0] as string;
+ }
+ if (typeof content === "string") {
+ if (content.length) {
+ if (content[0] === "▍") {
+ return ;
+ }
+ }
+
+ const match = /language-(\w+)/.exec(className || "");
+
+ return !inline ? (
+
+ ) : (
+
+ {content}
+
+ );
+ }
+ },
+ }}
+ >
+ {isEmpty && !chat.stream_url ? EMPTY_OUTPUT_SEND_MESSAGE : chatMessage}
+
+ {editedFlag}
+
+ );
+};
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/helpers/convert-files.ts b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/helpers/convert-files.ts
new file mode 100644
index 000000000..a9933b2dd
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/helpers/convert-files.ts
@@ -0,0 +1,20 @@
+export const convertFiles = (
+ files:
+ | (
+ | string
+ | {
+ path: string;
+ type: string;
+ name: string;
+ }
+ )[]
+ | undefined,
+) => {
+ if (!files) return [];
+ return files.map((file) => {
+ if (typeof file === "string") {
+ return file;
+ }
+ return file.path;
+ });
+};
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/newChatMessage.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/newChatMessage.tsx
index 67deec4cd..fffe7bc6e 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/newChatMessage.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/newChatMessage.tsx
@@ -1,6 +1,5 @@
import { ProfileIcon } from "@/components/core/appHeaderComponent/components/ProfileIcon";
import { ContentBlockDisplay } from "@/components/core/chatComponents/ContentBlockDisplay";
-import { TextShimmer } from "@/components/ui/TextShimmer";
import { useUpdateMessage } from "@/controllers/API/queries/messages";
import { CustomProfileIcon } from "@/customization/components/custom-profile-icon";
import { ENABLE_DATASTAX_LANGFLOW } from "@/customization/feature-flags";
@@ -8,11 +7,7 @@ import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import { useUtilityStore } from "@/stores/utilityStore";
import Convert from "ansi-to-html";
-import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useRef, useState } from "react";
-import Markdown from "react-markdown";
-import rehypeMathjax from "rehype-mathjax";
-import remarkGfm from "remark-gfm";
import Robot from "../../../../../assets/robot.png";
import IconComponent, {
ForwardedIconComponent,
@@ -27,10 +22,12 @@ import useTabVisibility from "../../../../../shared/hooks/use-tab-visibility";
import useAlertStore from "../../../../../stores/alertStore";
import { chatMessagePropsType } from "../../../../../types/components";
import { cn } from "../../../../../utils/utils";
-import LogoIcon from "./components/chatLogoIcon";
+import { ErrorView } from "./components/contentView";
+import { MarkdownField } from "./components/editMessage";
import { EditMessageButton } from "./components/editMessageButton/newMessageOptions";
import EditMessageField from "./components/editMessageField/newEditMessageField";
import FileCardWrapper from "./components/fileCardWrapper";
+import { convertFiles } from "./helpers/convert-files";
export default function ChatMessage({
chat,
@@ -63,6 +60,7 @@ export default function ChatMessage({
const chatMessageString = chat.message ? chat.message.toString() : "";
setChatMessage(chatMessageString);
}, [chat]);
+
const playgroundScrollBehaves = useUtilityStore(
(state) => state.playgroundScrollBehaves,
);
@@ -167,27 +165,6 @@ export default function ChatMessage({
const isEmpty = decodedMessage?.trim() === "";
const { mutate: updateMessageMutation } = useUpdateMessage();
- const convertFiles = (
- files:
- | (
- | string
- | {
- path: string;
- type: string;
- name: string;
- }
- )[]
- | undefined,
- ) => {
- if (!files) return [];
- return files.map((file) => {
- if (typeof file === "string") {
- return file;
- }
- return file.path;
- });
- };
-
const handleEditMessage = (message: string) => {
updateMessageMutation(
{
@@ -252,176 +229,14 @@ export default function ChatMessage({
const blocks = chat.content_blocks ?? [];
return (
-
-
- {!showError && lastMessage ? (
-
-
-
-
- Flow running...
-
-
-
- ) : (
-
-
- {blocks.map((block, blockIndex) => (
-
- {block.contents.map((content, contentIndex) => {
- if (content.type === "error") {
- return (
-
-
-
- {content.component && (
- <>
-
- An error occured in the{" "}
- {
- fitViewNode(
- chat.properties?.source?.id ?? "",
- );
- closeChat?.();
- }}
- >
- {content.component}
- {" "}
- Component, stopping your flow. See below for
- more details.
-
- >
- )}
-
-
-
- Error details:
-
- {content.field && (
-
Field: {content.field}
- )}
- {content.reason && (
-
- (
-
- {props.children}
-
- ),
- p({ node, ...props }) {
- return (
-
- {props.children}
-
- );
- },
- code: ({
- node,
- inline,
- className,
- children,
- ...props
- }) => {
- let content = children as string;
- if (
- Array.isArray(children) &&
- children.length === 1 &&
- typeof children[0] === "string"
- ) {
- content = children[0] as string;
- }
- if (typeof content === "string") {
- if (content.length) {
- if (content[0] === "▍") {
- return (
-
- );
- }
- }
-
- const match = /language-(\w+)/.exec(
- className || "",
- );
-
- return !inline ? (
-
- ) : (
-
- {content}
-
- );
- }
- },
- }}
- >
- {content.reason}
-
-
- )}
- {content.solution && (
-
-
- Steps to fix:
-
-
- - Check the component settings
- - Ensure all required fields are filled
- - Re-run your flow
-
-
- )}
-
-
- );
- }
- return null;
- })}
-
- ))}
-
- )}
-
-
+
);
}
@@ -568,100 +383,12 @@ export default function ChatMessage({
onCancel={() => setEditMessage(false)}
/>
) : (
- <>
-
-
- {props.children}
-
- );
- },
- ol({ node, ...props }) {
- return (
-
- {props.children}
-
- );
- },
- ul({ node, ...props }) {
- return (
-
- );
- },
- pre({ node, ...props }) {
- return <>{props.children}>;
- },
- code: ({
- node,
- inline,
- className,
- children,
- ...props
- }) => {
- let content = children as string;
- if (
- Array.isArray(children) &&
- children.length === 1 &&
- typeof children[0] === "string"
- ) {
- content = children[0] as string;
- }
- if (typeof content === "string") {
- if (content.length) {
- if (content[0] === "▍") {
- return (
-
- );
- }
- }
-
- const match = /language-(\w+)/.exec(
- className || "",
- );
-
- return !inline ? (
-
- ) : (
-
- {content}
-
- );
- }
- },
- }}
- >
- {isEmpty && !chat.stream_url
- ? EMPTY_OUTPUT_SEND_MESSAGE
- : chatMessage}
-
- {editedFlag}
-
- >
+
)}
)}
@@ -672,95 +399,37 @@ export default function ChatMessage({
) : (
- {template ? (
- <>
-
diff --git a/src/frontend/src/modals/IOModal/components/chatView/newChatView.tsx b/src/frontend/src/modals/IOModal/components/chatView/newChatView.tsx
index 3d26268db..ab7c49bb6 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/newChatView.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/newChatView.tsx
@@ -91,8 +91,8 @@ export default function ChatView({
if (messages.length === 0 && !lockChat && chatInputNode) {
setChatValue(chatInputNode.data.node.template["input_value"].value ?? "");
- } else if (isTabHidden) {
- setChatValue("");
+ } else {
+ isTabHidden ? setChatValue("") : null;
}
setChatHistory(finalChatHistory);
diff --git a/src/frontend/src/modals/IOModal/components/chatViewWrapper/index.tsx b/src/frontend/src/modals/IOModal/components/chatViewWrapper/index.tsx
new file mode 100644
index 000000000..fa141dbc1
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/chatViewWrapper/index.tsx
@@ -0,0 +1,115 @@
+import ShadTooltip from "@/components/common/shadTooltipComponent";
+import { Button } from "@/components/ui/button";
+import { Separator } from "@/components/ui/separator";
+import { cn } from "@/utils/utils";
+import IconComponent from "../../../../components/common/genericIconComponent";
+import { ChatViewWrapperProps } from "../../types/chat-view-wrapper";
+import ChatView from "../chatView/newChatView";
+
+export const ChatViewWrapper = ({
+ selectedViewField,
+ visibleSession,
+ sessions,
+ sidebarOpen,
+ currentFlowId,
+ setSidebarOpen,
+ isPlayground,
+ setvisibleSession,
+ setSelectedViewField,
+ messagesFetched,
+ sessionId,
+ sendMessage,
+ chatValue,
+ setChatValue,
+ lockChat,
+ setLockChat,
+ canvasOpen,
+ setOpen,
+}: ChatViewWrapperProps) => {
+ return (
+
+
+ {visibleSession && sessions.length > 0 && sidebarOpen && (
+
+ {visibleSession === currentFlowId
+ ? "Default Session"
+ : `${visibleSession}`}
+
+ )}
+
+
+
+
Playground
+
+
+
+
+
+
+ {!isPlayground && }
+
+
+
+ {messagesFetched && (
+ {
+ setOpen(false);
+ }
+ }
+ />
+ )}
+
+
+ );
+};
diff --git a/src/frontend/src/modals/IOModal/components/selectedViewField/index.tsx b/src/frontend/src/modals/IOModal/components/selectedViewField/index.tsx
new file mode 100644
index 000000000..b1c6c0c9a
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/selectedViewField/index.tsx
@@ -0,0 +1,64 @@
+import { InputOutput } from "@/constants/enums";
+import { cn } from "@/utils/utils";
+import IconComponent from "../../../../components/common/genericIconComponent";
+import { SelectedViewFieldProps } from "../../types/selected-view-field";
+import IOFieldView from "../IOFieldView";
+import SessionView from "../SessionView";
+
+export const SelectedViewField = ({
+ selectedViewField,
+ setSelectedViewField,
+ haveChat,
+ inputs,
+ outputs,
+ sessions,
+ currentFlowId,
+ nodes,
+}: SelectedViewFieldProps) => {
+ return (
+ <>
+
+
+ {haveChat && (
+
+ )}
+ {
+ nodes.find((node) => node.id === selectedViewField?.id)?.data.node
+ .display_name
+ }
+
+
+ {inputs.some((input) => input.id === selectedViewField?.id) && (
+
+ )}
+ {outputs.some((output) => output.id === selectedViewField?.id) && (
+
+ )}
+ {sessions.some((session) => session === selectedViewField?.id) && (
+
+ )}
+
+
+ >
+ );
+};
diff --git a/src/frontend/src/modals/IOModal/components/sidebarOpenView/index.tsx b/src/frontend/src/modals/IOModal/components/sidebarOpenView/index.tsx
new file mode 100644
index 000000000..7ae8e4749
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/components/sidebarOpenView/index.tsx
@@ -0,0 +1,79 @@
+import ShadTooltip from "@/components/common/shadTooltipComponent";
+import { Button } from "@/components/ui/button";
+import IconComponent from "../../../../components/common/genericIconComponent";
+import { SidebarOpenViewProps } from "../../types/sidebar-open-view";
+import SessionSelector from "../IOFieldView/components/sessionSelector/newSessionSelector";
+
+export const SidebarOpenView = ({
+ sessions,
+ setSelectedViewField,
+ setvisibleSession,
+ handleDeleteSession,
+ visibleSession,
+ selectedViewField,
+}: SidebarOpenViewProps) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ {sessions.map((session, index) => (
+ {
+ handleDeleteSession(session);
+ if (selectedViewField?.id === session) {
+ setSelectedViewField(undefined);
+ }
+ }}
+ updateVisibleSession={(session) => {
+ setvisibleSession(session);
+ }}
+ toggleVisibility={() => {
+ setvisibleSession(session);
+ }}
+ isVisible={visibleSession === session}
+ inspectSession={(session) => {
+ setSelectedViewField({
+ id: session,
+ type: "Session",
+ });
+ }}
+ />
+ ))}
+
+
+ >
+ );
+};
diff --git a/src/frontend/src/modals/IOModal/newModal.tsx b/src/frontend/src/modals/IOModal/newModal.tsx
index e5ceabe39..69bb54ffd 100644
--- a/src/frontend/src/modals/IOModal/newModal.tsx
+++ b/src/frontend/src/modals/IOModal/newModal.tsx
@@ -8,7 +8,6 @@ import { useCallback, useEffect, useState } from "react";
import IconComponent from "../../components/common/genericIconComponent";
import ShadTooltip from "../../components/common/shadTooltipComponent";
import { Button } from "../../components/ui/button";
-import { InputOutput } from "../../constants/enums";
import useAlertStore from "../../stores/alertStore";
import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
@@ -16,10 +15,10 @@ import { useMessagesStore } from "../../stores/messagesStore";
import { IOModalPropsType } from "../../types/components";
import { cn } from "../../utils/utils";
import BaseModal from "../baseModal";
-import IOFieldView from "./components/IOFieldView";
-import SessionSelector from "./components/IOFieldView/components/sessionSelector/newSessionSelector";
-import SessionView from "./components/SessionView";
import ChatView from "./components/chatView/newChatView";
+import { ChatViewWrapper } from "./components/chatViewWrapper";
+import { SelectedViewField } from "./components/selectedViewField";
+import { SidebarOpenView } from "./components/sidebarOpenView";
export default function IOModal({
children,
@@ -292,217 +291,51 @@ export default function IOModal({
)}
{sidebarOpen && (
-
-
-
-
-
-
-
-
-
-
-
-
- {sessions.map((session, index) => (
- {
- handleDeleteSession(session);
- if (selectedViewField?.id === session) {
- setSelectedViewField(undefined);
- }
- }}
- updateVisibleSession={(session) => {
- setvisibleSession(session);
- }}
- toggleVisibility={() => {
- setvisibleSession(session);
- }}
- isVisible={visibleSession === session}
- inspectSession={(session) => {
- setSelectedViewField({
- id: session,
- type: "Session",
- });
- }}
- />
- ))}
-
-
+
)}
{selectedViewField && (
-
-
- {haveChat && (
-
- )}
- {
- nodes.find((node) => node.id === selectedViewField.id)
- ?.data.node.display_name
- }
-
-
- {inputs.some(
- (input) => input.id === selectedViewField.id,
- ) && (
-
- )}
- {outputs.some(
- (output) => output.id === selectedViewField.id,
- ) && (
-
- )}
- {sessions.some(
- (session) => session === selectedViewField.id,
- ) && (
-
- )}
-
-
+
)}
-
-
- {visibleSession && sessions.length > 0 && sidebarOpen && (
-
- {visibleSession === currentFlowId
- ? "Default Session"
- : `${visibleSession}`}
-
- )}
-
-
-
-
Playground
-
-
-
-
-
-
- {!isPlayground && }
-
-
- {haveChat ? (
-
- {messagesFetched && (
- {
- setOpen(false);
- }
- }
- />
- )}
-
- ) : (
-
- Select an IO component to view
-
- )}
-
+
)}
diff --git a/src/frontend/src/modals/IOModal/types/chat-view-wrapper.ts b/src/frontend/src/modals/IOModal/types/chat-view-wrapper.ts
new file mode 100644
index 000000000..020877612
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/types/chat-view-wrapper.ts
@@ -0,0 +1,23 @@
+export type ChatViewWrapperProps = {
+ selectedViewField: { type: string; id: string } | undefined;
+ visibleSession: string | undefined;
+ sessions: string[];
+ sidebarOpen: boolean;
+ currentFlowId: string;
+ setSidebarOpen: (open: boolean) => void;
+ isPlayground: boolean | undefined;
+ setvisibleSession: (session: string | undefined) => void;
+ setSelectedViewField: (
+ field: { type: string; id: string } | undefined,
+ ) => void;
+ haveChat: { type: string; id: string; displayName: string } | undefined;
+ messagesFetched: boolean;
+ sessionId: string;
+ sendMessage: (options: { repeat: number; files?: string[] }) => Promise;
+ chatValue: string;
+ setChatValue: (value: string) => void;
+ lockChat: boolean;
+ setLockChat: (locked: boolean) => void;
+ canvasOpen: boolean | undefined;
+ setOpen: (open: boolean) => void;
+};
diff --git a/src/frontend/src/modals/IOModal/types/selected-view-field.ts b/src/frontend/src/modals/IOModal/types/selected-view-field.ts
new file mode 100644
index 000000000..b828e6f1a
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/types/selected-view-field.ts
@@ -0,0 +1,21 @@
+import { Node } from "reactflow";
+export type SelectedViewFieldProps = {
+ selectedViewField: { type: string; id: string } | undefined;
+ setSelectedViewField: (
+ field: { type: string; id: string } | undefined,
+ ) => void;
+ haveChat: { type: string; id: string; displayName: string } | undefined;
+ inputs: Array<{
+ type: string;
+ id: string;
+ displayName: string;
+ }>;
+ outputs: Array<{
+ type: string;
+ id: string;
+ displayName: string;
+ }>;
+ sessions: string[];
+ currentFlowId: string;
+ nodes: Node[];
+};
diff --git a/src/frontend/src/modals/IOModal/types/sidebar-open-view.ts b/src/frontend/src/modals/IOModal/types/sidebar-open-view.ts
new file mode 100644
index 000000000..047c6e431
--- /dev/null
+++ b/src/frontend/src/modals/IOModal/types/sidebar-open-view.ts
@@ -0,0 +1,10 @@
+export type SidebarOpenViewProps = {
+ sessions: string[];
+ setSelectedViewField: (
+ field: { type: string; id: string } | undefined,
+ ) => void;
+ setvisibleSession: (session: string | undefined) => void;
+ handleDeleteSession: (session: string) => void;
+ visibleSession: string | undefined;
+ selectedViewField: { type: string; id: string } | undefined;
+};