fix chat UI covering canvas when closed + update to add sending graph data button with message

pull/9266/head
Bentlybro 2025-01-17 12:50:31 +00:00
parent b055d16199
commit a42147d178
2 changed files with 270 additions and 120 deletions

View File

@ -1,3 +1,10 @@
.launcher-container {
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
}
.custom-launcher-button {
background-color: #8b5cf6 !important;
border: none !important;
@ -12,56 +19,97 @@
transition: all 0.2s ease-in-out !important;
width: 60px !important;
z-index: 999 !important;
}
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.custom-launcher-button:hover {
.custom-launcher-button:hover {
background-color: #7c3aed !important;
transform: scale(1.1) !important;
}
}
.rcw-launcher {
.capture-graph-button {
width: 40px;
height: 40px;
color: #fff;
background-color: #4b5563;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
border: none;
outline: none;
position: fixed !important;
right: 35px !important;
bottom: 100px !important;
}
.capture-graph-button:hover {
background-color: #374151;
transform: scale(1.05);
}
.capture-graph-button:focus {
outline: 2px solid #60a5fa;
outline-offset: 2px;
}
.capture-graph-button.active {
background-color: #10b981;
box-shadow: 0 0 0 2px #fff, 0 0 0 4px #10b981;
}
.capture-graph-button.active:hover {
background-color: #059669;
}
.rcw-launcher {
display: none !important;
}
}
.rcw-widget-container {
.rcw-widget-container {
height: 65vh !important;
margin-bottom: 50px !important;
border-radius: 10px !important;
max-width: 610px !important;
width: 100% !important;
}
}
.rcw-conversation-container {
.rcw-conversation-container {
border-radius: 10px !important;
background-color: white !important;
border: none !important;
}
}
.rcw-header {
.rcw-header {
background-color: #8b5cf6 !important;
border-radius: 10px 10px 0 0 !important;
padding: 0px !important;
min-height: 0px !important;
}
}
.rcw-messages-container {
.rcw-messages-container {
background-color: white !important;
padding: 12px 8px !important;
max-width: 100% !important;
overflow-x: hidden !important;
font-size: 0.9rem !important;
}
}
.rcw-message {
.rcw-message {
padding: 4px 8px !important;
width: auto !important;
max-width: 100% !important;
display: flex !important;
flex-direction: column !important;
margin: 4px 0 !important;
}
}
.rcw-message-text {
.rcw-message-text {
background-color: #f3f4f6 !important;
color: #1f2937 !important;
border-radius: 8px !important;
@ -73,31 +121,50 @@
line-height: 1.4 !important;
overflow-x: auto !important;
margin: 0 !important;
}
}
.rcw-message-text pre {
.rcw-message-text pre {
max-width: 100% !important;
overflow-x: auto !important;
white-space: pre-wrap !important;
word-wrap: break-word !important;
margin: 8px 0 !important;
}
}
.rcw-message-text code {
.rcw-message-text code {
word-wrap: break-word !important;
white-space: pre-wrap !important;
display: block !important;
width: 100% !important;
}
}
.rcw-client .rcw-message-text {
.rcw-client .rcw-message-text {
background-color: #8b5cf6 !important;
color: white !important;
}
}
.rcw-sender {
.rcw-sender {
background-color: white !important;
padding: 10px !important;
border-radius: 0 0 10px 10px !important;
border-top: 1px solid #e5e7eb !important;
}
}
.rcw-send {
display: none !important;
}
.rcw-widget-container.rcw-close-widget-container {
pointer-events: none !important;
}
.rcw-widget-container.rcw-close-widget-container .rcw-conversation-container,
.rcw-widget-container.rcw-close-widget-container .rcw-sender {
pointer-events: none !important;
visibility: hidden !important;
display: none !important;
}
.rcw-widget-container.rcw-close-widget-container .launcher-container {
pointer-events: all !important;
}

View File

@ -5,6 +5,10 @@ import { Widget, addResponseMessage, addLinkSnippet, deleteMessages } from 'reac
import 'react-chat-widget/lib/styles.css';
import './OttoChatWidget.css';
import useSupabase from '../hooks/useSupabase';
import useAgentGraph from '../hooks/useAgentGraph';
import { Node, Edge } from '@xyflow/react';
import { useSearchParams } from 'next/navigation';
import { useToast } from '@/components/ui/use-toast';
interface Document {
url: string;
@ -22,19 +26,42 @@ interface Message {
response: string;
}
interface GraphData {
nodes: {
id: string;
type: string;
position: { x: number; y: number };
data: any;
}[];
edges: {
id: string;
source: string;
target: string;
sourceHandle: string | null;
targetHandle: string | null;
data: any;
}[];
}
interface ChatPayload {
query: string;
conversation_history: { query: string; response: string }[];
user_id: string;
message_id: string;
graph_data?: GraphData;
}
const OttoChatWidget = () => {
const [chatWindowOpen, setChatWindowOpen] = useState(false);
const [messages, setMessages] = useState<Message[]>([]);
const [includeGraphData, setIncludeGraphData] = useState(false);
const welcomeMessageSent = useRef(false);
const processingMessageId = useRef<number | null>(null);
const { user } = useSupabase();
const searchParams = useSearchParams();
const flowID = searchParams.get('flowID');
const { nodes, edges } = useAgentGraph(flowID || undefined);
const { toast } = useToast();
useEffect(() => {
if (!welcomeMessageSent.current) {
@ -58,6 +85,26 @@ const OttoChatWidget = () => {
addResponseMessage('Processing your question...');
try {
const graphData: GraphData | undefined = (includeGraphData && nodes && edges) ? {
nodes: nodes.map(node => ({
id: node.id,
type: node.type || 'custom',
position: { x: node.position.x, y: node.position.y },
data: node.data
})),
edges: edges.map(edge => ({
id: edge.id,
source: edge.source,
target: edge.target,
sourceHandle: edge.sourceHandle ?? null,
targetHandle: edge.targetHandle ?? null,
data: edge.data || {}
}))
} : undefined;
// Reset the includeGraphData flag after using it
setIncludeGraphData(false);
const payload: ChatPayload = {
query: newMessage,
conversation_history: messages.map(msg => ({
@ -65,7 +112,8 @@ const OttoChatWidget = () => {
response: msg.response
})),
user_id: user?.id || 'anonymous',
message_id: messageId
message_id: messageId,
graph_data: graphData
};
const response = await fetch('http://192.168.0.39:2344/ask', {
@ -119,6 +167,7 @@ const OttoChatWidget = () => {
autofocus={true}
emojis={true}
launcher={(handleToggle: () => void) => (
<div className="launcher-container">
<button
onClick={handleToggle}
className="custom-launcher-button"
@ -137,6 +186,40 @@ const OttoChatWidget = () => {
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
</svg>
</button>
{chatWindowOpen && nodes && edges && (
<button
onClick={() => {
setIncludeGraphData(prev => {
const newState = !prev;
toast({
title: newState
? "Graph data will be included with your next message"
: "Graph data will not be included with your next message",
duration: 2000,
});
return newState;
});
}}
className={`capture-graph-button ${includeGraphData ? 'active' : ''}`}
aria-label="Include graph data with next message"
>
<svg
viewBox="0 0 24 24"
width="20"
height="20"
stroke="currentColor"
strokeWidth="2"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
<circle cx="8.5" cy="8.5" r="1.5" />
<polyline points="21 15 16 10 5 21" />
</svg>
</button>
)}
</div>
)}
/>
);