@cmnd-ai/chatbot-react 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ChatProvider/index.js +55 -53
- package/dist/ChatProvider/useChatContext.d.ts +2 -2
- package/dist/ChatProvider/useChatContext.js +2 -2
- package/dist/components/ChatInputBox.d.ts +2 -1
- package/dist/components/ChatInputBox.js +3 -3
- package/dist/components/Conversation.d.ts +2 -1
- package/dist/components/Conversation.js +2 -2
- package/dist/components/ConversationsPanel/index.d.ts +15 -2
- package/dist/components/ConversationsPanel/index.js +56 -34
- package/dist/hooks/use-fetch-data.d.ts +1 -2
- package/dist/hooks/use-fetch-data.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/getChatBotConversationsList/index.d.ts +1 -1
- package/dist/services/getChatBotConversationsList/index.js +3 -2
- package/dist/type.d.ts +25 -0
- package/package.json +1 -1
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
3
|
-
import { MessageRole, } from "../type.js";
|
|
2
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
4
3
|
import postUserConversation from "../services/postUserConversation.js";
|
|
5
4
|
import getChatBotById from "../services/getchatBotById.js";
|
|
6
5
|
import patchChatbotConversationMemory from "../services/patchChatbotConversationMemory/index.js";
|
|
7
6
|
import deleteChatbotConversationMemory from "../services/deleteChatbotConversationMemory/index.js";
|
|
8
7
|
import parseUITools from "../utils/parseUITools.js";
|
|
9
8
|
import getTools from "../utils/getTools/index.js";
|
|
10
|
-
import
|
|
11
|
-
import { ConversationsPanel } from "../components/ConversationsPanel/index.js";
|
|
12
|
-
import useMessagesScroll from "../hooks/use-messages-scroll.js";
|
|
9
|
+
import { ConversationsPanel, } from "../components/ConversationsPanel/index.js";
|
|
13
10
|
let globalChatbotConversationId;
|
|
14
11
|
let globalChatbotProps;
|
|
15
12
|
export const ChatProviderContext = React.createContext(undefined);
|
|
@@ -57,9 +54,14 @@ function ChatProvider(props) {
|
|
|
57
54
|
const [canContinue] = useState(false);
|
|
58
55
|
const [isChatLoading, setIsChatLoading] = useState(false);
|
|
59
56
|
const [canSendMessage, setCanSendMessage] = useState(true);
|
|
60
|
-
const { messagesRef, resetMessagesScroll, isMessagesScrolledToBottom } = useMessagesScroll(messages);
|
|
61
57
|
const [chatbotConversationId, setChatbotConversationId] = useState(undefined);
|
|
62
58
|
const [enabledTools, setEnabledTools] = useState([]);
|
|
59
|
+
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
|
|
60
|
+
const [selectedConversation, setSelectedConversation] = useState(null);
|
|
61
|
+
const inputRef = useRef(null);
|
|
62
|
+
const [shouldFocusInput, setShouldFocusInput] = useState(false);
|
|
63
|
+
const [pendingSendText, setPendingSendText] = useState(null);
|
|
64
|
+
const conversationsPanelRef = useRef(null);
|
|
63
65
|
useEffect(() => {
|
|
64
66
|
globalChatbotConversationId = chatbotConversationId;
|
|
65
67
|
}, [chatbotConversationId]);
|
|
@@ -98,54 +100,48 @@ function ChatProvider(props) {
|
|
|
98
100
|
onData,
|
|
99
101
|
});
|
|
100
102
|
};
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const newAssistantMessage = {
|
|
133
|
-
unuseful: false,
|
|
134
|
-
hiddenFromUser: false,
|
|
135
|
-
role: MessageRole.ASSISTANT,
|
|
136
|
-
message: data.message,
|
|
137
|
-
};
|
|
138
|
-
setMessages([...newMessages, newAssistantMessage]);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
setCanSendMessage(false);
|
|
142
|
-
await postSessionMessage(newMessages, onData);
|
|
103
|
+
const toggleSidebar = () => {
|
|
104
|
+
setIsSidebarCollapsed((prev) => !prev);
|
|
105
|
+
};
|
|
106
|
+
const openSidePanel = () => {
|
|
107
|
+
setIsSidebarCollapsed(false);
|
|
108
|
+
};
|
|
109
|
+
const closeSidePanel = () => {
|
|
110
|
+
setIsSidebarCollapsed(true);
|
|
111
|
+
};
|
|
112
|
+
const createNewConversation = () => {
|
|
113
|
+
conversationsPanelRef.current?.handleNewChat();
|
|
114
|
+
};
|
|
115
|
+
const setMessageText = (text) => {
|
|
116
|
+
setInput(text);
|
|
117
|
+
setShouldFocusInput(true);
|
|
118
|
+
};
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (shouldFocusInput) {
|
|
121
|
+
inputRef.current?.focus();
|
|
122
|
+
if (inputRef.current) {
|
|
123
|
+
const len = inputRef.current.value.length;
|
|
124
|
+
inputRef.current.setSelectionRange(len, len);
|
|
125
|
+
}
|
|
126
|
+
setShouldFocusInput(false);
|
|
127
|
+
}
|
|
128
|
+
}, [input, shouldFocusInput]);
|
|
129
|
+
const sendMessage = (text) => {
|
|
130
|
+
if (typeof text === "string") {
|
|
131
|
+
setInput(text);
|
|
132
|
+
setShouldFocusInput(true);
|
|
133
|
+
setPendingSendText(text);
|
|
143
134
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
setError("Error sending message");
|
|
135
|
+
else {
|
|
136
|
+
conversationsPanelRef.current?.handleSendClick();
|
|
147
137
|
}
|
|
148
138
|
};
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
if (pendingSendText !== null && input === pendingSendText) {
|
|
141
|
+
conversationsPanelRef.current?.handleSendClick();
|
|
142
|
+
setPendingSendText(null);
|
|
143
|
+
}
|
|
144
|
+
}, [input, pendingSendText]);
|
|
149
145
|
if (loading)
|
|
150
146
|
return null;
|
|
151
147
|
return (_jsx(ChatProviderContext.Provider, { value: {
|
|
@@ -169,9 +165,15 @@ function ChatProvider(props) {
|
|
|
169
165
|
chatbotConversationId,
|
|
170
166
|
UITools: parseUITools(UITools),
|
|
171
167
|
},
|
|
172
|
-
|
|
168
|
+
createNewConversation,
|
|
169
|
+
toggleSidebar,
|
|
170
|
+
openSidePanel,
|
|
171
|
+
closeSidePanel,
|
|
172
|
+
setMessageText,
|
|
173
|
+
sendMessage,
|
|
174
|
+
}, children: error ? (_jsx("div", { children: "An error occured" })) : (_jsxs(_Fragment, { children: [props.children, _jsx(ConversationsPanel, { ref: conversationsPanelRef, organizationId: organizationId, chatbotId: chatbotId, baseUrl: baseUrl, theme: props.theme, enabledTools: getTools({
|
|
173
175
|
apiTools: enabledTools,
|
|
174
176
|
uiTools: parseUITools(UITools),
|
|
175
|
-
}), postSessionMessage: postSessionMessage, setChatbotConversationId: setChatbotConversationId, chatbotConversationId: chatbotConversationId, Components: Components, UITools: parseUITools(UITools), customStyles: props.customStyles })] })) }));
|
|
177
|
+
}), postSessionMessage: postSessionMessage, setChatbotConversationId: setChatbotConversationId, chatbotConversationId: chatbotConversationId, Components: Components, UITools: parseUITools(UITools), customStyles: props.customStyles, isSidebarCollapsed: isSidebarCollapsed, setIsSidebarCollapsed: setIsSidebarCollapsed, selectedConversation: selectedConversation, setSelectedConversation: setSelectedConversation, messages: messages, setMessages: setMessages, input: input, setInput: setInput, inputRef: inputRef })] })) }));
|
|
176
178
|
}
|
|
177
179
|
export default ChatProvider;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
export
|
|
1
|
+
declare const useCMNDChatContext: () => import("../type.js").CmndChatContext;
|
|
2
|
+
export { useCMNDChatContext };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
2
|
import { ChatProviderContext } from "./index.js";
|
|
3
|
-
const
|
|
3
|
+
const useCMNDChatContext = () => {
|
|
4
4
|
const context = useContext(ChatProviderContext);
|
|
5
5
|
if (!context)
|
|
6
6
|
throw new Error("Cmnd chat context must be wrapped in a provider");
|
|
7
7
|
return context;
|
|
8
8
|
};
|
|
9
|
-
export
|
|
9
|
+
export { useCMNDChatContext };
|
|
@@ -3,6 +3,7 @@ interface ChatInputBoxProps {
|
|
|
3
3
|
input: string;
|
|
4
4
|
setInput: (input: string) => void;
|
|
5
5
|
handleSendClick: () => void;
|
|
6
|
+
inputRef?: React.RefObject<HTMLInputElement>;
|
|
6
7
|
}
|
|
7
|
-
declare const ChatInputBox: ({ input, setInput, handleSendClick }: ChatInputBoxProps) => JSX.Element;
|
|
8
|
+
declare const ChatInputBox: ({ input, setInput, handleSendClick, inputRef, }: ChatInputBoxProps) => JSX.Element;
|
|
8
9
|
export default ChatInputBox;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
const ChatInputBox = ({ input, setInput, handleSendClick }) => {
|
|
3
|
-
return (_jsx("div", { className: "cmnd-input-wrapper", children: _jsx("input", { autoFocus: true, id: "cmnd-input", className: "cmnd-input", onKeyDown: e => {
|
|
2
|
+
const ChatInputBox = ({ input, setInput, handleSendClick, inputRef, }) => {
|
|
3
|
+
return (_jsx("div", { className: "cmnd-input-wrapper", children: _jsx("input", { ref: inputRef, autoFocus: true, id: "cmnd-input", className: "cmnd-input", onKeyDown: (e) => {
|
|
4
4
|
if (e.key === "Enter") {
|
|
5
5
|
handleSendClick();
|
|
6
6
|
}
|
|
7
|
-
}, autoComplete: "off", value: input, onChange: e => setInput(e.target.value), type: "text", placeholder: "Type something..." }) }));
|
|
7
|
+
}, autoComplete: "off", value: input, onChange: (e) => setInput(e.target.value), type: "text", placeholder: "Type something..." }) }));
|
|
8
8
|
};
|
|
9
9
|
export default ChatInputBox;
|
|
@@ -29,6 +29,7 @@ export interface ConversationProps {
|
|
|
29
29
|
organizationId: number;
|
|
30
30
|
isMessagesScrolledToBottom?: boolean;
|
|
31
31
|
resetMessagesScroll?: () => void;
|
|
32
|
+
inputRef?: React.RefObject<HTMLInputElement>;
|
|
32
33
|
}
|
|
33
|
-
declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, isMessagesScrolledToBottom, resetMessagesScroll, }: ConversationProps) => JSX.Element;
|
|
34
|
+
declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, isMessagesScrolledToBottom, resetMessagesScroll, inputRef, }: ConversationProps) => JSX.Element;
|
|
34
35
|
export default Conversation;
|
|
@@ -3,8 +3,8 @@ import Chatbubble from "./Chatbubble.js";
|
|
|
3
3
|
import LoadingBubble from "./LoadingBubble.js";
|
|
4
4
|
import ScrollToBottomButton from "./ScrollToBottomButton.js";
|
|
5
5
|
import ChatInputBox from "./ChatInputBox.js";
|
|
6
|
-
const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, isMessagesScrolledToBottom = true, resetMessagesScroll, }) => {
|
|
7
|
-
return (_jsxs("div", { className: "cmnd-conversations", children: [_jsxs("div", { ref: messagesRef, id: "messages", className: "cmnd-conversations-messages", children: [error, messages.map((m, i) => (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, customStyles: customStyles, hide: m.hiddenFromUser, message: m.message, role: m.role, toolCallDetails: m.tool, tools: enabledTools, postSessionMessage: postSessionMessage, messages: messages, setMessages: setMessages, id: m.id, setChatbotConversationId: setChatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, UITools: UITools, theme: theme, Components: Components }, i))), isChatLoading ? (_jsx(LoadingBubble, { customStyles: customStyles, chatbotId: chatbotId, organizationId: organizationId, theme: theme, Components: Components })) : null] }), _jsx(ScrollToBottomButton, { onClick: resetMessagesScroll || (() => { }), isVisible: !isMessagesScrolledToBottom && messages.length > 0, theme: theme, customStyles: customStyles }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick } })) : (_jsx(ChatInputBox, { input: input, setInput: setInput, handleSendClick: handleSendClick })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
|
|
6
|
+
const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, isMessagesScrolledToBottom = true, resetMessagesScroll, inputRef, }) => {
|
|
7
|
+
return (_jsxs("div", { className: "cmnd-conversations", children: [_jsxs("div", { ref: messagesRef, id: "messages", className: "cmnd-conversations-messages", children: [error, messages.map((m, i) => (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, customStyles: customStyles, hide: m.hiddenFromUser, message: m.message, role: m.role, toolCallDetails: m.tool, tools: enabledTools, postSessionMessage: postSessionMessage, messages: messages, setMessages: setMessages, id: m.id, setChatbotConversationId: setChatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, UITools: UITools, theme: theme, Components: Components }, i))), isChatLoading ? (_jsx(LoadingBubble, { customStyles: customStyles, chatbotId: chatbotId, organizationId: organizationId, theme: theme, Components: Components })) : null] }), _jsx(ScrollToBottomButton, { onClick: resetMessagesScroll || (() => { }), isVisible: !isMessagesScrolledToBottom && messages.length > 0, theme: theme, customStyles: customStyles }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick, inputRef } })) : (_jsx(ChatInputBox, { input: input, setInput: setInput, handleSendClick: handleSendClick, inputRef: inputRef })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
|
|
8
8
|
canSendMessage,
|
|
9
9
|
handleSendClick,
|
|
10
10
|
} })) : (_jsx("button", { className: "cmnd-send-button", onClick: handleSendClick, children: "Send" }))] })] }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { Dispatch, SetStateAction } from "react";
|
|
2
|
-
import { InputFieldProps, SendButtonProps } from "../../type.js";
|
|
2
|
+
import { ChatbotConversation, InputFieldProps, SendButtonProps } from "../../type.js";
|
|
3
3
|
interface ConversationsPanelProps {
|
|
4
4
|
organizationId: number;
|
|
5
5
|
chatbotId: number;
|
|
@@ -28,6 +28,19 @@ interface ConversationsPanelProps {
|
|
|
28
28
|
dateStyle?: React.CSSProperties;
|
|
29
29
|
deleteButtonStyle?: React.CSSProperties;
|
|
30
30
|
};
|
|
31
|
+
isSidebarCollapsed?: boolean;
|
|
32
|
+
setIsSidebarCollapsed?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
33
|
+
selectedConversation: ChatbotConversation | null;
|
|
34
|
+
setSelectedConversation: React.Dispatch<React.SetStateAction<ChatbotConversation | null>>;
|
|
35
|
+
messages: any[];
|
|
36
|
+
setMessages: React.Dispatch<React.SetStateAction<any[]>>;
|
|
37
|
+
input: string;
|
|
38
|
+
setInput: React.Dispatch<React.SetStateAction<string>>;
|
|
39
|
+
inputRef: React.RefObject<HTMLInputElement>;
|
|
31
40
|
}
|
|
32
|
-
export
|
|
41
|
+
export interface ConversationsPanelRef {
|
|
42
|
+
handleSendClick: () => void;
|
|
43
|
+
handleNewChat: () => void;
|
|
44
|
+
}
|
|
45
|
+
export declare const ConversationsPanel: React.ForwardRefExoticComponent<ConversationsPanelProps & React.RefAttributes<ConversationsPanelRef>>;
|
|
33
46
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState, useEffect, } from "react";
|
|
2
|
+
import React, { useState, useEffect, forwardRef, useImperativeHandle, } from "react";
|
|
3
3
|
import useFetchData from "../../hooks/use-fetch-data.js";
|
|
4
4
|
import getChatBotConversationsList from "../../services/getChatBotConversationsList/index.js";
|
|
5
5
|
import Conversation from "../Conversation.js";
|
|
@@ -10,14 +10,17 @@ import getConversationLocalStorageKey from "../../utils/getConversationLocalStor
|
|
|
10
10
|
import saveConversationIdToLocalStorage from "../../utils/saveConversationIdToLocalStorage/index.js";
|
|
11
11
|
import getUTCDateTime from "../../utils/getUTCDateTime/index.js";
|
|
12
12
|
import useMessagesScroll from "../../hooks/use-messages-scroll.js";
|
|
13
|
-
export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme = "light", enabledTools = [], setChatbotConversationId, chatbotConversationId, postSessionMessage, Components, UITools, customStyles, }) => {
|
|
14
|
-
const [selectedConversation, setSelectedConversation] = useState(null);
|
|
15
|
-
const [messages, setMessages] = useState([]);
|
|
16
|
-
const [input, setInput] = useState("");
|
|
13
|
+
export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseUrl, theme = "light", enabledTools = [], setChatbotConversationId, chatbotConversationId, postSessionMessage, Components, UITools, customStyles, isSidebarCollapsed, setIsSidebarCollapsed, selectedConversation, setSelectedConversation, messages, setMessages, input, setInput, inputRef, }, ref) => {
|
|
17
14
|
const [isChatLoading, setIsChatLoading] = useState(false);
|
|
18
15
|
const [canSendMessage, setCanSendMessage] = useState(true);
|
|
19
16
|
const [conversationIds, setConversationIds] = useState([]);
|
|
20
|
-
const
|
|
17
|
+
const isSidebarCollapsedProp = typeof isSidebarCollapsed === "boolean" ? isSidebarCollapsed : false;
|
|
18
|
+
const setIsSidebarCollapsedProp = setIsSidebarCollapsed;
|
|
19
|
+
const [internalSidebarCollapsed, setInternalSidebarCollapsed] = useState(false);
|
|
20
|
+
const isSidebarCollapsedFinal = typeof isSidebarCollapsed === "boolean"
|
|
21
|
+
? isSidebarCollapsed
|
|
22
|
+
: internalSidebarCollapsed;
|
|
23
|
+
const setIsSidebarCollapsedFinal = setIsSidebarCollapsedProp || setInternalSidebarCollapsed;
|
|
21
24
|
const { messagesRef, resetMessagesScroll, isMessagesScrolledToBottom } = useMessagesScroll(messages);
|
|
22
25
|
const themeColors = {
|
|
23
26
|
light: {
|
|
@@ -72,23 +75,27 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
72
75
|
setConversationIds([]);
|
|
73
76
|
}
|
|
74
77
|
};
|
|
75
|
-
const { data, loading, error, refetch } = useFetchData(() => {
|
|
78
|
+
const { data, loading, error, refetch } = useFetchData(async () => {
|
|
76
79
|
// Only fetch if we have conversation IDs
|
|
77
80
|
if (conversationIds.length === 0) {
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
return { chatbotConversations: [] };
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return await getChatBotConversationsList({
|
|
85
|
+
organizationId,
|
|
86
|
+
chatbotId,
|
|
87
|
+
conversationIds,
|
|
88
|
+
baseUrl,
|
|
89
|
+
}).catch((error) => {
|
|
90
|
+
// Ignore any error from axios and return an empty list
|
|
91
|
+
console.error("Error fetching conversations (ignored):", error);
|
|
92
|
+
return { chatbotConversations: [] };
|
|
84
93
|
});
|
|
85
94
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
baseUrl,
|
|
91
|
-
});
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error("Error fetching conversations (sync):", error);
|
|
97
|
+
return { chatbotConversations: [] };
|
|
98
|
+
}
|
|
92
99
|
}, [organizationId, chatbotId, conversationIds, baseUrl]);
|
|
93
100
|
const handleSendClick = () => {
|
|
94
101
|
if (!input.trim() || !canSendMessage)
|
|
@@ -119,7 +126,8 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
119
126
|
});
|
|
120
127
|
refetchConversationIds();
|
|
121
128
|
if (selectedConversation &&
|
|
122
|
-
selectedConversation.chatbotConversationTitle ===
|
|
129
|
+
selectedConversation.chatbotConversationTitle ===
|
|
130
|
+
"New Conversation") {
|
|
123
131
|
setSelectedConversation({
|
|
124
132
|
...selectedConversation,
|
|
125
133
|
chatbotConversationId: newConversationId,
|
|
@@ -213,6 +221,10 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
213
221
|
return dateB.getTime() - dateA.getTime();
|
|
214
222
|
});
|
|
215
223
|
}, [data?.chatbotConversations, selectedConversation]);
|
|
224
|
+
useImperativeHandle(ref, () => ({
|
|
225
|
+
handleSendClick,
|
|
226
|
+
handleNewChat,
|
|
227
|
+
}));
|
|
216
228
|
return (_jsxs("div", { className: "cmnd-conversations-panel", style: {
|
|
217
229
|
display: "flex",
|
|
218
230
|
height: "100%",
|
|
@@ -220,7 +232,7 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
220
232
|
color: colors.text,
|
|
221
233
|
...customStyles?.panelStyle,
|
|
222
234
|
}, children: [_jsxs("div", { className: "cmnd-conversations-sidebar", style: {
|
|
223
|
-
width:
|
|
235
|
+
width: isSidebarCollapsedFinal ? "50px" : "300px",
|
|
224
236
|
borderRight: `1px solid ${colors.border}`,
|
|
225
237
|
display: "flex",
|
|
226
238
|
flexDirection: "column",
|
|
@@ -228,15 +240,17 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
228
240
|
transition: "width 0.3s ease",
|
|
229
241
|
...customStyles?.sidebarStyle,
|
|
230
242
|
}, children: [_jsxs("div", { className: "cmnd-conversations-header", style: {
|
|
231
|
-
padding:
|
|
243
|
+
padding: isSidebarCollapsedFinal ? "12px 8px" : "16px",
|
|
232
244
|
borderBottom: `1px solid ${colors.border}`,
|
|
233
245
|
display: "flex",
|
|
234
|
-
justifyContent:
|
|
246
|
+
justifyContent: isSidebarCollapsedFinal
|
|
247
|
+
? "center"
|
|
248
|
+
: "space-between",
|
|
235
249
|
alignItems: "center",
|
|
236
|
-
flexDirection:
|
|
237
|
-
gap:
|
|
250
|
+
flexDirection: isSidebarCollapsedFinal ? "column" : "row",
|
|
251
|
+
gap: isSidebarCollapsedFinal ? "8px" : "0",
|
|
238
252
|
...customStyles?.headerStyle,
|
|
239
|
-
}, children: [!
|
|
253
|
+
}, children: [!isSidebarCollapsedFinal && (_jsx("h3", { style: {
|
|
240
254
|
margin: 0,
|
|
241
255
|
fontSize: "16px",
|
|
242
256
|
fontWeight: "600",
|
|
@@ -244,8 +258,10 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
244
258
|
}, children: "Conversations" })), _jsxs("div", { style: {
|
|
245
259
|
display: "flex",
|
|
246
260
|
gap: "8px",
|
|
247
|
-
flexDirection:
|
|
248
|
-
}, children: [_jsx("button", { className: "cmnd-toggle-sidebar-button", onClick: () =>
|
|
261
|
+
flexDirection: isSidebarCollapsedFinal ? "column" : "row",
|
|
262
|
+
}, children: [_jsx("button", { className: "cmnd-toggle-sidebar-button", onClick: () => setIsSidebarCollapsedFinal((prev) => !prev), title: isSidebarCollapsedFinal
|
|
263
|
+
? "Expand Sidebar"
|
|
264
|
+
: "Collapse Sidebar", style: {
|
|
249
265
|
background: colors.button,
|
|
250
266
|
border: "none",
|
|
251
267
|
color: theme === "light" ? "#ffffff" : colors.text,
|
|
@@ -282,7 +298,7 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
282
298
|
overflowY: "auto",
|
|
283
299
|
padding: "12px",
|
|
284
300
|
...customStyles?.conversationListStyle,
|
|
285
|
-
}, children:
|
|
301
|
+
}, children: isSidebarCollapsedFinal ? (_jsx("div", { style: {
|
|
286
302
|
textAlign: "center",
|
|
287
303
|
padding: "8px",
|
|
288
304
|
color: colors.secondaryText,
|
|
@@ -291,19 +307,25 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
291
307
|
textAlign: "center",
|
|
292
308
|
padding: "20px",
|
|
293
309
|
color: colors.secondaryText,
|
|
294
|
-
}, children: "Loading conversations..." })) : error && allConversations.length === 0 ? (_jsx("div", { style: {
|
|
310
|
+
}, children: "Loading conversations..." })) : error && allConversations.length === 0 ? (_jsx("div", { style: {
|
|
311
|
+
textAlign: "center",
|
|
312
|
+
padding: "20px",
|
|
313
|
+
color: "#ff6b6b",
|
|
314
|
+
}, children: "Error loading conversations" })) : allConversations.length === 0 ? (_jsx("div", { style: {
|
|
295
315
|
textAlign: "center",
|
|
296
316
|
padding: "20px",
|
|
297
317
|
color: colors.secondaryText,
|
|
298
318
|
}, children: "No conversations yet" })) : (allConversations.map((conversation) => (_jsx(ConversationCard, { conversation: conversation, isActive: selectedConversation?.chatbotConversationId ===
|
|
299
319
|
conversation.chatbotConversationId, onClick: () => {
|
|
300
|
-
if (conversation.chatbotConversationTitle ===
|
|
320
|
+
if (conversation.chatbotConversationTitle ===
|
|
321
|
+
"New Conversation") {
|
|
301
322
|
}
|
|
302
323
|
else {
|
|
303
324
|
handleConversationSelect(conversation);
|
|
304
325
|
}
|
|
305
326
|
}, onDelete: () => {
|
|
306
|
-
if (conversation.chatbotConversationTitle ===
|
|
327
|
+
if (conversation.chatbotConversationTitle ===
|
|
328
|
+
"New Conversation") {
|
|
307
329
|
setSelectedConversation(null);
|
|
308
330
|
setMessages([]);
|
|
309
331
|
}
|
|
@@ -329,5 +351,5 @@ export const ConversationsPanel = ({ organizationId, chatbotId, baseUrl, theme =
|
|
|
329
351
|
fontSize: "16px",
|
|
330
352
|
textAlign: "center",
|
|
331
353
|
padding: "20px",
|
|
332
|
-
}, children: _jsx("div", { children: _jsx("div", { children: "Select a conversation or start a new one" }) }) })) : (_jsx(Conversation, { messages: messages, setMessages: setMessages, handleSendClick: handleSendClick, input: input, setInput: setInput, isChatLoading: isChatLoading, error: error ? "Error loading conversations" : null, messagesRef: messagesRef, setChatbotConversationId: setChatbotConversationId, chatbotConversationId: chatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, canSendMessage: canSendMessage, enabledTools: enabledTools, postSessionMessage: postSessionMessage, theme: theme, Components: Components, UITools: UITools, customStyles: customStyles, setCurrentConversationMemory: setCurrentConversationMemory, chatbotId: chatbotId, organizationId: organizationId, isMessagesScrolledToBottom: isMessagesScrolledToBottom, resetMessagesScroll: resetMessagesScroll })) })] }));
|
|
333
|
-
};
|
|
354
|
+
}, children: _jsx("div", { children: _jsx("div", { children: "Select a conversation or start a new one" }) }) })) : (_jsx(Conversation, { messages: messages, setMessages: setMessages, handleSendClick: handleSendClick, input: input, setInput: setInput, isChatLoading: isChatLoading, error: error ? "Error loading conversations" : null, messagesRef: messagesRef, setChatbotConversationId: setChatbotConversationId, chatbotConversationId: chatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, canSendMessage: canSendMessage, enabledTools: enabledTools, postSessionMessage: postSessionMessage, theme: theme, Components: Components, UITools: UITools, customStyles: customStyles, setCurrentConversationMemory: setCurrentConversationMemory, chatbotId: chatbotId, organizationId: organizationId, isMessagesScrolledToBottom: isMessagesScrolledToBottom, resetMessagesScroll: resetMessagesScroll, inputRef: inputRef })) })] }));
|
|
355
|
+
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { AxiosPromise } from "axios";
|
|
2
1
|
type UseFetchDataResult<T = any> = {
|
|
3
2
|
loading: boolean;
|
|
4
3
|
error: boolean;
|
|
5
4
|
data: T;
|
|
6
5
|
refetch: () => void;
|
|
7
6
|
};
|
|
8
|
-
declare const useFetchData: <T = any>(apiCallFn: () =>
|
|
7
|
+
declare const useFetchData: <T = any>(apiCallFn: () => Promise<T>, deps?: any[]) => UseFetchDataResult<T>;
|
|
9
8
|
export default useFetchData;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,3 +2,4 @@ export { default as ChatProvider } from "./ChatProvider/index.js";
|
|
|
2
2
|
export { ConversationsPanel } from "./components/ConversationsPanel/index.js";
|
|
3
3
|
export { CmndChatContext, InputFieldProps, SendButtonProps, CustomStyles, CMNDChatMemory, ChatbotConversation, ChatbotConversationsResponse, } from "./type.js";
|
|
4
4
|
export { setCurrentConversationMemory, deleteCurrentConversationMemory, } from "./ChatProvider/index.js";
|
|
5
|
+
export { useCMNDChatContext } from "./ChatProvider/useChatContext.js";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { default as ChatProvider } from "./ChatProvider/index.js";
|
|
2
2
|
export { ConversationsPanel } from "./components/ConversationsPanel/index.js";
|
|
3
3
|
export { setCurrentConversationMemory, deleteCurrentConversationMemory, } from "./ChatProvider/index.js";
|
|
4
|
+
export { useCMNDChatContext } from "./ChatProvider/useChatContext.js";
|
|
@@ -3,5 +3,5 @@ declare const getChatBotConversationsList: ({ organizationId, chatbotId, convers
|
|
|
3
3
|
chatbotId: number;
|
|
4
4
|
conversationIds: number[];
|
|
5
5
|
baseUrl: string;
|
|
6
|
-
}) => Promise<
|
|
6
|
+
}) => Promise<any>;
|
|
7
7
|
export default getChatBotConversationsList;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { chatbot } from "../../constants/endpoints.js";
|
|
3
|
-
const getChatBotConversationsList = ({ organizationId, chatbotId, conversationIds, baseUrl, }) => {
|
|
3
|
+
const getChatBotConversationsList = async ({ organizationId, chatbotId, conversationIds, baseUrl, }) => {
|
|
4
4
|
const endpoint = chatbot.getChatBotConversationsList({
|
|
5
5
|
organizationId,
|
|
6
6
|
chatbotId,
|
|
7
7
|
conversationIds,
|
|
8
8
|
});
|
|
9
|
-
|
|
9
|
+
const response = await axios.get(`${baseUrl}${endpoint}`);
|
|
10
|
+
return response.data;
|
|
10
11
|
};
|
|
11
12
|
export default getChatBotConversationsList;
|
package/dist/type.d.ts
CHANGED
|
@@ -2,12 +2,37 @@ import { CSSProperties } from "react";
|
|
|
2
2
|
import { ConversationProps } from "./components/Conversation.js";
|
|
3
3
|
export interface CmndChatContext {
|
|
4
4
|
props: Partial<ConversationProps>;
|
|
5
|
+
/**
|
|
6
|
+
* Create a new conversation (resets state, starts a new chat thread)
|
|
7
|
+
*/
|
|
8
|
+
createNewConversation: () => void;
|
|
9
|
+
/**
|
|
10
|
+
* Toggle the sidebar open/collapsed state
|
|
11
|
+
*/
|
|
12
|
+
toggleSidebar: () => void;
|
|
13
|
+
/**
|
|
14
|
+
* Open the sidebar (set collapsed to false)
|
|
15
|
+
*/
|
|
16
|
+
openSidePanel: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Close the sidebar (set collapsed to true)
|
|
19
|
+
*/
|
|
20
|
+
closeSidePanel: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the message text in the input box
|
|
23
|
+
*/
|
|
24
|
+
setMessageText: (text: string) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Send the current message, or set and send if text is provided
|
|
27
|
+
*/
|
|
28
|
+
sendMessage: (text?: string) => void;
|
|
5
29
|
}
|
|
6
30
|
export interface InputFieldProps {
|
|
7
31
|
input: string;
|
|
8
32
|
setInput: (input: string) => void;
|
|
9
33
|
canSendMessage: boolean;
|
|
10
34
|
handleSendClick: () => void;
|
|
35
|
+
inputRef?: React.RefObject<HTMLInputElement> | React.RefObject<HTMLTextAreaElement> | React.RefObject<HTMLTextAreaElement>;
|
|
11
36
|
}
|
|
12
37
|
export interface SendButtonProps {
|
|
13
38
|
handleSendClick: () => void;
|