diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 8491f6873..9b90b435e 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -25,6 +25,7 @@ "ace-builds": "^1.16.0", "ansi-to-html": "^0.7.2", "axios": "^1.3.2", + "base64-js": "^1.5.1", "lodash": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", @@ -5862,6 +5863,25 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index feb11e814..55749b635 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -20,6 +20,7 @@ "ace-builds": "^1.16.0", "ansi-to-html": "^0.7.2", "axios": "^1.3.2", + "base64-js": "^1.5.1", "lodash": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", diff --git a/src/frontend/src/modals/chatModal/chatMessage/index.tsx b/src/frontend/src/modals/chatModal/chatMessage/index.tsx index d960a149b..60a07e1b7 100644 --- a/src/frontend/src/modals/chatModal/chatMessage/index.tsx +++ b/src/frontend/src/modals/chatModal/chatMessage/index.tsx @@ -1,11 +1,10 @@ -import { - ChatBubbleOvalLeftEllipsisIcon, -} from "@heroicons/react/24/outline"; +import { ChatBubbleOvalLeftEllipsisIcon } from "@heroicons/react/24/outline"; import { useState } from "react"; import { ChatMessageType } from "../../../types/chat"; import { classNames } from "../../../utils"; -import AiIcon from "../../../assets/Gooey Ring-5s-271px.svg" +import AiIcon from "../../../assets/Gooey Ring-5s-271px.svg"; import { UserIcon } from "@heroicons/react/24/solid"; +import FileCard from "../fileComponent"; var Convert = require("ansi-to-html"); var convert = new Convert({ newline: true }); @@ -20,17 +19,16 @@ export default function ChatMessage({ chat }: { chat: ChatMessageType }) { >
- {!chat.isSend && } - {chat.isSend && } + {!chat.isSend && } + {chat.isSend && }
{!chat.isSend ? (
-
+
{hidden && chat.thought && chat.thought !== "" && (
setHidden((prev) => !prev)} @@ -42,17 +40,29 @@ export default function ChatMessage({ chat }: { chat: ChatMessageType }) { {chat.thought && chat.thought !== "" && !hidden && (
setHidden((prev) => !prev)} - className=" text-start inline-block w-full pb-3 pt-3 px-5 cursor-pointer" + className=" text-start inline-block rounded-md h-full border border-gray-300 + bg-gray-100 w-[95%] pb-3 pt-3 px-2 ml-3 cursor-pointer scrollbar-hide overflow-scroll" dangerouslySetInnerHTML={{ __html: convert.toHtml(chat.thought), }} >
)} {chat.thought && chat.thought !== "" && !hidden &&

} -
- {chat.message} +
+ {chat.file ? ( +
+ ) : ( + + {chat.message} +
+ +
+
+ )}
diff --git a/src/frontend/src/modals/chatModal/fileComponent/index.tsx b/src/frontend/src/modals/chatModal/fileComponent/index.tsx new file mode 100644 index 000000000..b6393f112 --- /dev/null +++ b/src/frontend/src/modals/chatModal/fileComponent/index.tsx @@ -0,0 +1,36 @@ +import { CloudArrowDownIcon, DocumentIcon } from "@heroicons/react/24/outline"; +import * as base64js from 'base64-js'; + +export default function FileCard({ fileName, content, fileType }) { + const handleDownload = () => { + const byteArray = new Uint8Array(base64js.toByteArray(content)); + const blob = new Blob([byteArray], { type: 'application/octet-stream' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = fileName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); + }; + + return ( + + ); +} diff --git a/src/frontend/src/modals/chatModal/index.tsx b/src/frontend/src/modals/chatModal/index.tsx index d19bf37d5..b5413a517 100644 --- a/src/frontend/src/modals/chatModal/index.tsx +++ b/src/frontend/src/modals/chatModal/index.tsx @@ -34,11 +34,15 @@ export default function ChatModal({ const addChatHistory = ( message: string, isSend: boolean, - thought?: string + thought?: string, + file?:Blob ) => { setChatHistory((old) => { let newChat = _.cloneDeep(old); - if (thought) { + if(file){ + newChat.push({ message, isSend,file }); + } + else if (thought) { newChat.push({ message, isSend, thought }); } else { newChat.push({ message, isSend }); @@ -57,7 +61,7 @@ export default function ChatModal({ console.log("Received data:", data); //get chat history if (Array.isArray(data)) { - console.log("entrou"); + console.log(data); setChatHistory((_) => { let newChatHistory: ChatMessageType[] = []; @@ -67,7 +71,16 @@ export default function ChatModal({ is_bot: boolean; message: string; type: string; + data?:string; }) => { + if(chatItem.type==="file"){ + newChatHistory.push({ + isSend: !chatItem.is_bot, + message: chatItem.message, + thought: chatItem.intermediate_steps, + file:chatItem.data + }); + } newChatHistory.push({ isSend: !chatItem.is_bot, message: chatItem.message, @@ -82,8 +95,12 @@ export default function ChatModal({ addChatHistory(data.message, false, data.intermediate_steps); setLockChat(false) } + if (data.type=="file"){ + console.log(data) + } // Do something with the data received from the WebSocket }; + newWs.onclose=(e)=>{console.log(e.reason)} setWs(newWs); return () => { diff --git a/src/frontend/src/types/chat/index.ts b/src/frontend/src/types/chat/index.ts index dc0c25b15..b32968290 100644 --- a/src/frontend/src/types/chat/index.ts +++ b/src/frontend/src/types/chat/index.ts @@ -2,4 +2,4 @@ import { ReactFlowInstance } from 'reactflow'; import { FlowType } from "../flow"; export type ChatType = {flow:FlowType,reactFlowInstance:ReactFlowInstance} -export type ChatMessageType = { message: string; isSend: boolean, thought?:string } \ No newline at end of file +export type ChatMessageType = { message: string; isSend: boolean, thought?:string,file?:string } \ No newline at end of file