fix chat UI covering canvas when closed + update to add sending graph data button with message
parent
b055d16199
commit
a42147d178
|
@ -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,13 +19,54 @@
|
|||
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 {
|
||||
background-color: #7c3aed !important;
|
||||
transform: scale(1.1) !important;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
@ -101,3 +149,22 @@
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue