From b4a51bce3bb05738ec9cd0efd1b795ba19cbc640 Mon Sep 17 00:00:00 2001
From: "A.J. Shulman" <Shulman.aj@gmail.com>
Date: Fri, 8 Nov 2024 10:44:51 -0500
Subject: looks better still some things to work out

---
 .../chatbot/chatboxcomponents/MessageComponent.tsx | 40 +++++-----------------
 1 file changed, 8 insertions(+), 32 deletions(-)

(limited to 'src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx')

diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
index e463d15bf..44dedca78 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
@@ -34,18 +34,11 @@ interface MessageComponentProps {
  * @param {MessageComponentProps} props - The props for the component.
  */
 const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollowUpClick, onCitationClick }) => {
-    // State for managing whether the dropdown is open or closed for processing info
     const [dropdownOpen, setDropdownOpen] = useState(false);
 
-    /**
-     * Renders the content of the message based on the type (e.g., grounded text, normal text).
-     * @param {MessageContent} item - The content item to render.
-     * @returns {JSX.Element} JSX element rendering the content.
-     */
     const renderContent = (item: MessageContent) => {
         const i = item.index;
 
-        // Handle grounded text with citations
         if (item.type === TEXT_TYPE.GROUNDED) {
             const citation_ids = item.citation_ids || [];
             return (
@@ -56,34 +49,25 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
                         if (!citation) return null;
                         return (
                             <button key={i + idx} className="citation-button" onClick={() => onCitationClick(citation)}>
-                                {i + 1}
+                                [{idx + 1}]
                             </button>
                         );
                     })}
                 </span>
             );
-        }
-
-        // Handle normal text
-        else if (item.type === TEXT_TYPE.NORMAL) {
+        } else if (item.type === TEXT_TYPE.NORMAL) {
             return (
                 <span key={i} className="normal-text">
                     <ReactMarkdown>{item.text}</ReactMarkdown>
                 </span>
             );
-        }
-
-        // Handle query type content
-        else if ('query' in item) {
+        } else if ('query' in item) {
             return (
                 <span key={i} className="query-text">
                     <ReactMarkdown>{JSON.stringify(item.query)}</ReactMarkdown>
                 </span>
             );
-        }
-
-        // Fallback for any other content type
-        else {
+        } else {
             return (
                 <span key={i}>
                     <ReactMarkdown>{JSON.stringify(item)}</ReactMarkdown>
@@ -92,24 +76,18 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
         }
     };
 
-    // Check if the message contains processing information (thoughts/actions)
     const hasProcessingInfo = message.processing_info && message.processing_info.length > 0;
 
-    /**
-     * Renders processing information such as thoughts or actions during message handling.
-     * @param {ProcessingInfo} info - The processing information to render.
-     * @returns {JSX.Element | null} JSX element rendering the processing info or null.
-     */
     const renderProcessingInfo = (info: ProcessingInfo) => {
         if (info.type === PROCESSING_TYPE.THOUGHT) {
             return (
-                <div key={info.index} className="dropdown-item">
+                <div key={info.index} className="processing-item">
                     <strong>Thought:</strong> {info.content}
                 </div>
             );
         } else if (info.type === PROCESSING_TYPE.ACTION) {
             return (
-                <div key={info.index} className="dropdown-item">
+                <div key={info.index} className="processing-item">
                     <strong>Action:</strong> {info.content}
                 </div>
             );
@@ -119,6 +97,8 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
 
     return (
         <div className={`message ${message.role}`}>
+            <div className="message-content">{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div>
+
             {/* Processing Information Dropdown */}
             {hasProcessingInfo && (
                 <div className="processing-info">
@@ -126,13 +106,9 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
                         {dropdownOpen ? 'Hide Agent Thoughts/Actions' : 'Show Agent Thoughts/Actions'}
                     </button>
                     {dropdownOpen && <div className="info-content">{message.processing_info.map(renderProcessingInfo)}</div>}
-                    <br />
                 </div>
             )}
 
-            {/* Message Content */}
-            <div className="message-content">{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div>
-
             {/* Follow-up Questions Section */}
             {message.follow_up_questions && message.follow_up_questions.length > 0 && (
                 <div className="follow-up-questions">
-- 
cgit v1.2.3-70-g09d2


From 309085a660f4f932935adba812214a948aacdfc3 Mon Sep 17 00:00:00 2001
From: "A.J. Shulman" <Shulman.aj@gmail.com>
Date: Fri, 8 Nov 2024 11:07:45 -0500
Subject: displays much better with citations inline

---
 .../nodes/chatbot/chatboxcomponents/ChatBox.scss   | 77 ++++++++++++----------
 .../chatbot/chatboxcomponents/MessageComponent.tsx | 43 +++++++++---
 2 files changed, 78 insertions(+), 42 deletions(-)

(limited to 'src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx')

diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
index ea461388f..9cf760a12 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
@@ -86,11 +86,10 @@ $transition: all 0.2s ease-in-out;
             height: 48px;
             margin-left: 10px;
             cursor: pointer;
-            transition: $transition;
             display: flex;
             align-items: center;
             justify-content: center;
-            position: relative;
+            transition: $transition;
 
             &:hover {
                 background-color: darken($primary-color, 10%);
@@ -102,12 +101,12 @@ $transition: all 0.2s ease-in-out;
             }
 
             .spinner {
-                height: 24px;
-                width: 24px;
+                width: 20px;
+                height: 20px;
                 border: 3px solid rgba(255, 255, 255, 0.3);
                 border-top: 3px solid #fff;
                 border-radius: 50%;
-                animation: spin 1s linear infinite;
+                animation: spin 0.6s linear infinite;
             }
         }
     }
@@ -143,12 +142,14 @@ $transition: all 0.2s ease-in-out;
 
 .message {
     max-width: 75%;
-    padding: 14px 18px;
-    border-radius: 16px;
+    padding: 12px 16px;
+    border-radius: 12px;
     font-size: 15px;
     line-height: 1.6;
     box-shadow: 0 1px 3px $shadow-color;
     word-wrap: break-word;
+    display: flex;
+    flex-direction: column;
 
     &.user {
         align-self: flex-end;
@@ -164,10 +165,6 @@ $transition: all 0.2s ease-in-out;
         border-bottom-left-radius: 4px;
     }
 
-    .message-content {
-        // Additional styles if needed
-    }
-
     .toggle-info {
         margin-top: 10px;
         background-color: transparent;
@@ -178,7 +175,7 @@ $transition: all 0.2s ease-in-out;
         font-size: 14px;
         cursor: pointer;
         transition: $transition;
-        margin-bottom: 12px; // Adds space between button and thoughts/actions text
+        margin-bottom: 16px;
 
         &:hover {
             background-color: rgba($primary-color, 0.1);
@@ -186,7 +183,12 @@ $transition: all 0.2s ease-in-out;
     }
 
     .processing-info {
-        margin-top: 10px;
+        margin-bottom: 12px;
+        padding: 10px 15px;
+        background-color: #f9f9f9;
+        border-radius: 8px;
+        box-shadow: 0 1px 3px $shadow-color;
+        font-size: 14px;
 
         .processing-item {
             margin-bottom: 5px;
@@ -194,6 +196,35 @@ $transition: all 0.2s ease-in-out;
             color: $light-text-color;
         }
     }
+
+    .message-content {
+        background-color: inherit;
+        padding: 10px;
+        border-radius: 8px;
+        font-size: 15px;
+        line-height: 1.5;
+
+        .citation-button {
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 22px;
+            height: 22px;
+            border-radius: 50%;
+            background-color: rgba(0, 0, 0, 0.1);
+            color: $text-color;
+            font-size: 12px;
+            font-weight: bold;
+            margin-left: 5px;
+            cursor: pointer;
+            transition: $transition;
+
+            &:hover {
+                background-color: rgba($primary-color, 0.2);
+                color: #fff;
+            }
+        }
+    }
 }
 
 .follow-up-questions {
@@ -229,26 +260,6 @@ $transition: all 0.2s ease-in-out;
     }
 }
 
-.citation-button {
-    display: inline-flex;
-    align-items: center;
-    justify-content: center;
-    width: 22px;
-    height: 22px;
-    border-radius: 50%;
-    background-color: rgba(0, 0, 0, 0.1);
-    color: $text-color;
-    font-size: 12px;
-    font-weight: bold;
-    margin-left: 5px;
-    cursor: pointer;
-    transition: $transition;
-
-    &:hover {
-        background-color: rgba(0, 0, 0, 0.2);
-    }
-}
-
 .uploading-overlay {
     position: absolute;
     top: 0;
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
index 44dedca78..120e20001 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
@@ -34,40 +34,57 @@ interface MessageComponentProps {
  * @param {MessageComponentProps} props - The props for the component.
  */
 const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollowUpClick, onCitationClick }) => {
+    // State for managing whether the dropdown is open or closed for processing info
     const [dropdownOpen, setDropdownOpen] = useState(false);
 
+    /**
+     * Renders the content of the message based on the type (e.g., grounded text, normal text).
+     * @param {MessageContent} item - The content item to render.
+     * @returns {JSX.Element} JSX element rendering the content.
+     */
     const renderContent = (item: MessageContent) => {
         const i = item.index;
 
+        // Handle grounded text with citations
         if (item.type === TEXT_TYPE.GROUNDED) {
             const citation_ids = item.citation_ids || [];
             return (
                 <span key={i} className="grounded-text">
-                    <ReactMarkdown>{item.text}</ReactMarkdown>
+                    {item.text}
                     {citation_ids.map((id, idx) => {
                         const citation = message.citations?.find(c => c.citation_id === id);
                         if (!citation) return null;
                         return (
                             <button key={i + idx} className="citation-button" onClick={() => onCitationClick(citation)}>
-                                [{idx + 1}]
+                                {i + idx + 1}
                             </button>
                         );
                     })}
+                    <br />
                 </span>
             );
-        } else if (item.type === TEXT_TYPE.NORMAL) {
+        }
+
+        // Handle normal text
+        else if (item.type === TEXT_TYPE.NORMAL) {
             return (
                 <span key={i} className="normal-text">
                     <ReactMarkdown>{item.text}</ReactMarkdown>
                 </span>
             );
-        } else if ('query' in item) {
+        }
+
+        // Handle query type content
+        else if ('query' in item) {
             return (
                 <span key={i} className="query-text">
                     <ReactMarkdown>{JSON.stringify(item.query)}</ReactMarkdown>
                 </span>
             );
-        } else {
+        }
+
+        // Fallback for any other content type
+        else {
             return (
                 <span key={i}>
                     <ReactMarkdown>{JSON.stringify(item)}</ReactMarkdown>
@@ -76,18 +93,24 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
         }
     };
 
+    // Check if the message contains processing information (thoughts/actions)
     const hasProcessingInfo = message.processing_info && message.processing_info.length > 0;
 
+    /**
+     * Renders processing information such as thoughts or actions during message handling.
+     * @param {ProcessingInfo} info - The processing information to render.
+     * @returns {JSX.Element | null} JSX element rendering the processing info or null.
+     */
     const renderProcessingInfo = (info: ProcessingInfo) => {
         if (info.type === PROCESSING_TYPE.THOUGHT) {
             return (
-                <div key={info.index} className="processing-item">
+                <div key={info.index} className="dropdown-item">
                     <strong>Thought:</strong> {info.content}
                 </div>
             );
         } else if (info.type === PROCESSING_TYPE.ACTION) {
             return (
-                <div key={info.index} className="processing-item">
+                <div key={info.index} className="dropdown-item">
                     <strong>Action:</strong> {info.content}
                 </div>
             );
@@ -97,8 +120,6 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
 
     return (
         <div className={`message ${message.role}`}>
-            <div className="message-content">{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div>
-
             {/* Processing Information Dropdown */}
             {hasProcessingInfo && (
                 <div className="processing-info">
@@ -106,9 +127,13 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
                         {dropdownOpen ? 'Hide Agent Thoughts/Actions' : 'Show Agent Thoughts/Actions'}
                     </button>
                     {dropdownOpen && <div className="info-content">{message.processing_info.map(renderProcessingInfo)}</div>}
+                    <br />
                 </div>
             )}
 
+            {/* Message Content */}
+            <div className="message-content">{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div>
+
             {/* Follow-up Questions Section */}
             {message.follow_up_questions && message.follow_up_questions.length > 0 && (
                 <div className="follow-up-questions">
-- 
cgit v1.2.3-70-g09d2


From 9e447814b551c352709296ae562f1f50480320f5 Mon Sep 17 00:00:00 2001
From: "A.J. Shulman" <Shulman.aj@gmail.com>
Date: Fri, 8 Nov 2024 11:09:25 -0500
Subject: Displays markdown again now

---
 .../chatbot/chatboxcomponents/MessageComponent.tsx | 35 ++++++++++++++--------
 1 file changed, 23 insertions(+), 12 deletions(-)

(limited to 'src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx')

diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
index 120e20001..1a3d4dbc6 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/MessageComponent.tsx
@@ -11,6 +11,7 @@ import React, { useState } from 'react';
 import { observer } from 'mobx-react';
 import { AssistantMessage, Citation, MessageContent, PROCESSING_TYPE, ProcessingInfo, TEXT_TYPE } from '../types/types';
 import ReactMarkdown from 'react-markdown';
+import remarkGfm from 'remark-gfm';
 
 /**
  * Props for the MessageComponentBox.
@@ -50,17 +51,27 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
             const citation_ids = item.citation_ids || [];
             return (
                 <span key={i} className="grounded-text">
-                    {item.text}
-                    {citation_ids.map((id, idx) => {
-                        const citation = message.citations?.find(c => c.citation_id === id);
-                        if (!citation) return null;
-                        return (
-                            <button key={i + idx} className="citation-button" onClick={() => onCitationClick(citation)}>
-                                {i + idx + 1}
-                            </button>
-                        );
-                    })}
-                    <br />
+                    <ReactMarkdown
+                        remarkPlugins={[remarkGfm]}
+                        components={{
+                            p: ({ node, children }) => (
+                                <span className="grounded-text">
+                                    {children}
+                                    {citation_ids.map((id, idx) => {
+                                        const citation = message.citations?.find(c => c.citation_id === id);
+                                        if (!citation) return null;
+                                        return (
+                                            <button key={i + idx} className="citation-button" onClick={() => onCitationClick(citation)} style={{ display: 'inline-flex', alignItems: 'center', marginLeft: '4px' }}>
+                                                {i + idx + 1}
+                                            </button>
+                                        );
+                                    })}
+                                    <br />
+                                </span>
+                            ),
+                        }}>
+                        {item.text}
+                    </ReactMarkdown>
                 </span>
             );
         }
@@ -69,7 +80,7 @@ const MessageComponentBox: React.FC<MessageComponentProps> = ({ message, onFollo
         else if (item.type === TEXT_TYPE.NORMAL) {
             return (
                 <span key={i} className="normal-text">
-                    <ReactMarkdown>{item.text}</ReactMarkdown>
+                    <ReactMarkdown remarkPlugins={[remarkGfm]}>{item.text}</ReactMarkdown>
                 </span>
             );
         }
-- 
cgit v1.2.3-70-g09d2

