-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Enhance error handling, message editing and prompt display (#…
…5310) * 📝 (newChatMessage.tsx): add event listener to handle tab visibility change and update state accordingly 📝 (newChatMessage.tsx): remove event listener when component unmounts to prevent memory leaks * ✨ (use-tab-visibility.tsx): introduce custom hook useTabVisibility to track tab visibility changes in the browser 📝 (newChatMessage.tsx, newChatView.tsx): import and use useTabVisibility hook to handle tab visibility changes and update chat behavior accordingly * 📝 (newChatMessage.tsx): remove duplicate import of useTabVisibility and update import path 📝 (newChatView.tsx): remove duplicate import of useTabVisibility and update import path ✨ (use-tab-visibility.tsx): create a new custom hook to track tab visibility changes in the browser * reducing to smaller components * 📝 (frontend): remove unused imports and clean up code in various files to improve code readability and maintainability * 📝 (editMessage/index.tsx): Rename EditMessage component to MarkdownField for better clarity and consistency 📝 (newChatMessage.tsx): Replace EditMessage component with MarkdownField component for rendering chat messages with markdown support 📝 (newChatView.tsx): Add conditional rendering to display a message when no chat messages are fetched ✨ (chatViewWrapper/index.tsx): Add messageFetched prop to ChatView component to handle messages fetching status and improve component functionality. * prompt viedw * Refactor chat view component and remove unused prop * [autofix.ci] apply automated fixes --------- Co-authored-by: anovazzi1 <otavio2204@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
- Loading branch information
1 parent
9a8f721
commit 01c1d47
Showing
13 changed files
with
703 additions
and
590 deletions.
There are no files selected for viewing
1 change: 0 additions & 1 deletion
1
...c/modals/IOModal/components/IOFieldView/components/sessionSelector/newSessionSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
...ntend/src/modals/IOModal/components/chatView/chatMessage/components/contentView/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<> | ||
<div className="w-5/6 max-w-[768px] py-4 word-break-break-word"> | ||
<AnimatePresence mode="wait"> | ||
{!showError && lastMessage ? ( | ||
<motion.div | ||
key="loading" | ||
initial={{ opacity: 1 }} | ||
exit={{ opacity: 0 }} | ||
className="flex w-full gap-4 rounded-md p-2" | ||
> | ||
<LogoIcon /> | ||
<div className="flex items-center"> | ||
<TextShimmer className="" duration={1}> | ||
Flow running... | ||
</TextShimmer> | ||
</div> | ||
</motion.div> | ||
) : ( | ||
<motion.div | ||
key="error" | ||
initial={{ opacity: 0 }} | ||
animate={{ opacity: 1 }} | ||
transition={{ duration: 0.3 }} | ||
className="flex w-full gap-4 rounded-md p-2" | ||
> | ||
<LogoIcon /> | ||
{blocks.map((block, blockIndex) => ( | ||
<div | ||
key={blockIndex} | ||
className="w-full rounded-xl border border-error-red-border bg-error-red p-4 text-[14px] text-foreground" | ||
> | ||
{block.contents.map((content, contentIndex) => { | ||
if (content.type === "error") { | ||
return ( | ||
<div className="" key={contentIndex}> | ||
<div className="mb-2 flex items-center"> | ||
<ForwardedIconComponent | ||
className="mr-2 h-[18px] w-[18px] text-destructive" | ||
name="OctagonAlert" | ||
/> | ||
{content.component && ( | ||
<> | ||
<span> | ||
An error occured in the{" "} | ||
<span | ||
className={cn( | ||
closeChat ?? "cursor-pointer underline", | ||
)} | ||
onClick={() => { | ||
fitViewNode( | ||
chat.properties?.source?.id ?? "", | ||
); | ||
closeChat?.(); | ||
}} | ||
> | ||
<strong>{content.component}</strong> | ||
</span>{" "} | ||
Component, stopping your flow. See below for | ||
more details. | ||
</span> | ||
</> | ||
)} | ||
</div> | ||
<div> | ||
<h3 className="pb-3 font-semibold"> | ||
Error details: | ||
</h3> | ||
{content.field && ( | ||
<p className="pb-1">Field: {content.field}</p> | ||
)} | ||
{content.reason && ( | ||
<span className=""> | ||
<Markdown | ||
linkTarget="_blank" | ||
remarkPlugins={[remarkGfm]} | ||
components={{ | ||
a: ({ node, ...props }) => ( | ||
<a | ||
href={props.href} | ||
target="_blank" | ||
className="underline" | ||
rel="noopener noreferrer" | ||
> | ||
{props.children} | ||
</a> | ||
), | ||
p({ node, ...props }) { | ||
return ( | ||
<span className="inline-block w-fit max-w-full"> | ||
{props.children} | ||
</span> | ||
); | ||
}, | ||
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 ( | ||
<span className="form-modal-markdown-span"></span> | ||
); | ||
} | ||
} | ||
|
||
const match = /language-(\w+)/.exec( | ||
className || "", | ||
); | ||
|
||
return !inline ? ( | ||
<CodeTabsComponent | ||
language={(match && match[1]) || ""} | ||
code={String(content).replace( | ||
/\n$/, | ||
"", | ||
)} | ||
/> | ||
) : ( | ||
<code | ||
className={className} | ||
{...props} | ||
> | ||
{content} | ||
</code> | ||
); | ||
} | ||
}, | ||
}} | ||
> | ||
{content.reason} | ||
</Markdown> | ||
</span> | ||
)} | ||
{content.solution && ( | ||
<div className="mt-4"> | ||
<h3 className="pb-3 font-semibold"> | ||
Steps to fix: | ||
</h3> | ||
<ol className="list-decimal pl-5"> | ||
<li>Check the component settings</li> | ||
<li>Ensure all required fields are filled</li> | ||
<li>Re-run your flow</li> | ||
</ol> | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
return null; | ||
})} | ||
</div> | ||
))} | ||
</motion.div> | ||
)} | ||
</AnimatePresence> | ||
</div> | ||
</> | ||
); | ||
}; |
83 changes: 83 additions & 0 deletions
83
...ntend/src/modals/IOModal/components/chatView/chatMessage/components/editMessage/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<div className="w-full items-baseline gap-2"> | ||
<Markdown | ||
remarkPlugins={[remarkGfm]} | ||
linkTarget="_blank" | ||
rehypePlugins={[rehypeMathjax]} | ||
className={cn( | ||
"markdown prose flex w-fit max-w-full flex-col items-baseline text-[14px] font-normal word-break-break-word dark:prose-invert", | ||
isEmpty ? "text-muted-foreground" : "text-primary", | ||
)} | ||
components={{ | ||
p({ node, ...props }) { | ||
return <span className="w-fit max-w-full">{props.children}</span>; | ||
}, | ||
ol({ node, ...props }) { | ||
return <ol className="max-w-full">{props.children}</ol>; | ||
}, | ||
ul({ node, ...props }) { | ||
return <ul className="max-w-full">{props.children}</ul>; | ||
}, | ||
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 <span className="form-modal-markdown-span"></span>; | ||
} | ||
} | ||
|
||
const match = /language-(\w+)/.exec(className || ""); | ||
|
||
return !inline ? ( | ||
<CodeTabsComponent | ||
language={(match && match[1]) || ""} | ||
code={String(content).replace(/\n$/, "")} | ||
/> | ||
) : ( | ||
<code className={className} {...props}> | ||
{content} | ||
</code> | ||
); | ||
} | ||
}, | ||
}} | ||
> | ||
{isEmpty && !chat.stream_url ? EMPTY_OUTPUT_SEND_MESSAGE : chatMessage} | ||
</Markdown> | ||
{editedFlag} | ||
</div> | ||
); | ||
}; |
20 changes: 20 additions & 0 deletions
20
src/frontend/src/modals/IOModal/components/chatView/chatMessage/helpers/convert-files.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
}); | ||
}; |
Oops, something went wrong.