@patternfly/chatbot 6.3.0 → 6.4.0-prerelease.3
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/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +3 -3
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +17 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.js +25 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +22 -0
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/FileDropZone/FileDropZone.d.ts +1 -2
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +1 -10
- package/dist/cjs/Message/Message.d.ts +4 -2
- package/dist/cjs/Message/Message.js +4 -4
- package/dist/cjs/Message/Message.test.js +26 -0
- package/dist/cjs/Message/MessageInput.d.ts +3 -1
- package/dist/cjs/Message/MessageInput.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.d.ts +2 -2
- package/dist/cjs/MessageBar/MessageBar.d.ts +2 -2
- package/dist/cjs/MessageBox/MessageBox.js +1 -1
- package/dist/cjs/MessageDivider/MessageDivider.d.ts +9 -0
- package/dist/cjs/MessageDivider/MessageDivider.js +23 -0
- package/dist/cjs/MessageDivider/MessageDivider.test.d.ts +1 -0
- package/dist/cjs/MessageDivider/MessageDivider.test.js +29 -0
- package/dist/cjs/MessageDivider/index.d.ts +2 -0
- package/dist/cjs/MessageDivider/index.js +23 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +1 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +4 -4
- package/dist/cjs/ResponseActions/ResponseActions.test.js +6 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/css/main.css +56 -55
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/MessageDivider/package.json +1 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +5 -5
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +17 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.js +22 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +20 -0
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/FileDropZone/FileDropZone.d.ts +1 -2
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +1 -7
- package/dist/esm/Message/Message.d.ts +4 -2
- package/dist/esm/Message/Message.js +4 -4
- package/dist/esm/Message/Message.test.js +26 -0
- package/dist/esm/Message/MessageInput.d.ts +3 -1
- package/dist/esm/Message/MessageInput.js +2 -2
- package/dist/esm/MessageBar/AttachButton.d.ts +2 -2
- package/dist/esm/MessageBar/MessageBar.d.ts +2 -2
- package/dist/esm/MessageBox/MessageBox.js +1 -1
- package/dist/esm/MessageDivider/MessageDivider.d.ts +9 -0
- package/dist/esm/MessageDivider/MessageDivider.js +21 -0
- package/dist/esm/MessageDivider/MessageDivider.test.d.ts +1 -0
- package/dist/esm/MessageDivider/MessageDivider.test.js +24 -0
- package/dist/esm/MessageDivider/index.d.ts +2 -0
- package/dist/esm/MessageDivider/index.js +2 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +1 -0
- package/dist/esm/ResponseActions/ResponseActions.js +5 -5
- package/dist/esm/ResponseActions/ResponseActions.test.js +6 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDividers.tsx +24 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +15 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +39 -7
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +17 -3
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +9 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx +196 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +16 -3
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +33 -1
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotDisplayMode.tsx +486 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotTranscripts.tsx +565 -0
- package/src/Chatbot/Chatbot.scss +1 -1
- package/src/ChatbotContent/ChatbotContent.scss +1 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -2
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +58 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +34 -12
- package/src/ChatbotFooter/ChatbotFooter.scss +1 -1
- package/src/ChatbotHeader/ChatbotHeader.scss +3 -3
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx +25 -0
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx +64 -0
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/ChatbotToggle/ChatbotToggle.scss +2 -2
- package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +6 -9
- package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +6 -9
- package/src/FileDropZone/FileDropZone.tsx +2 -2
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +3 -27
- package/src/Message/Message.scss +9 -7
- package/src/Message/Message.test.tsx +35 -0
- package/src/Message/Message.tsx +8 -4
- package/src/Message/MessageInput.tsx +5 -1
- package/src/MessageBar/AttachButton.tsx +2 -2
- package/src/MessageBar/MessageBar.tsx +2 -2
- package/src/MessageBar/SendButton.scss +3 -3
- package/src/MessageBox/JumpButton.scss +1 -1
- package/src/MessageBox/MessageBox.tsx +1 -1
- package/src/MessageDivider/MessageDivider.scss +45 -0
- package/src/MessageDivider/MessageDivider.test.tsx +24 -0
- package/src/MessageDivider/MessageDivider.tsx +35 -0
- package/src/MessageDivider/index.ts +3 -0
- package/src/ResponseActions/ResponseActions.test.tsx +6 -1
- package/src/ResponseActions/ResponseActions.tsx +24 -3
- package/src/index.ts +3 -0
- package/src/main.scss +1 -52
- package/dist/cjs/Message/CodeBlockMessage/ExpandableSectionForSyntaxHighlighter.d.ts +0 -62
- package/dist/cjs/Message/CodeBlockMessage/ExpandableSectionForSyntaxHighlighter.js +0 -139
- package/dist/esm/Message/CodeBlockMessage/ExpandableSectionForSyntaxHighlighter.d.ts +0 -62
- package/dist/esm/Message/CodeBlockMessage/ExpandableSectionForSyntaxHighlighter.js +0 -133
- package/src/Message/CodeBlockMessage/ExpandableSectionForSyntaxHighlighter.tsx +0 -223
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import React, { FunctionComponent, MouseEvent, useEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Brand,
|
|
5
|
+
DropdownList,
|
|
6
|
+
DropdownItem,
|
|
7
|
+
Page,
|
|
8
|
+
Masthead,
|
|
9
|
+
MastheadMain,
|
|
10
|
+
MastheadBrand,
|
|
11
|
+
MastheadLogo,
|
|
12
|
+
PageSidebarBody,
|
|
13
|
+
PageSidebar,
|
|
14
|
+
MastheadToggle,
|
|
15
|
+
PageToggleButton,
|
|
16
|
+
SkipToContent,
|
|
17
|
+
Drawer,
|
|
18
|
+
DrawerContent,
|
|
19
|
+
DrawerContentBody,
|
|
20
|
+
DrawerPanelContent,
|
|
21
|
+
DropdownGroup
|
|
22
|
+
} from '@patternfly/react-core';
|
|
23
|
+
|
|
24
|
+
import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle';
|
|
25
|
+
import Chatbot, { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot';
|
|
26
|
+
import ChatbotContent from '@patternfly/chatbot/dist/dynamic/ChatbotContent';
|
|
27
|
+
import ChatbotWelcomePrompt from '@patternfly/chatbot/dist/dynamic/ChatbotWelcomePrompt';
|
|
28
|
+
import ChatbotFooter, { ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';
|
|
29
|
+
import MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar';
|
|
30
|
+
import MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox';
|
|
31
|
+
import Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message';
|
|
32
|
+
import ChatbotConversationHistoryNav, {
|
|
33
|
+
Conversation
|
|
34
|
+
} from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
|
|
35
|
+
import ChatbotHeader, {
|
|
36
|
+
ChatbotHeaderMenu,
|
|
37
|
+
ChatbotHeaderMain,
|
|
38
|
+
ChatbotHeaderTitle,
|
|
39
|
+
ChatbotHeaderActions,
|
|
40
|
+
ChatbotHeaderSelectorDropdown,
|
|
41
|
+
ChatbotHeaderOptionsDropdown,
|
|
42
|
+
ChatbotHeaderCloseButton
|
|
43
|
+
} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
|
|
44
|
+
import PFIconLogoColor from '../UI/PF-IconLogo-Color.svg';
|
|
45
|
+
import PFIconLogoReverse from '../UI/PF-IconLogo-Reverse.svg';
|
|
46
|
+
import { BarsIcon } from '@patternfly/react-icons';
|
|
47
|
+
import ExpandIcon from '@patternfly/react-icons/dist/esm/icons/expand-icon';
|
|
48
|
+
import OpenDrawerRightIcon from '@patternfly/react-icons/dist/esm/icons/open-drawer-right-icon';
|
|
49
|
+
import OutlinedWindowRestoreIcon from '@patternfly/react-icons/dist/esm/icons/outlined-window-restore-icon';
|
|
50
|
+
import userAvatar from '../Messages/user_avatar.svg';
|
|
51
|
+
import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
|
|
52
|
+
import '@patternfly/react-core/dist/styles/base.css';
|
|
53
|
+
import '@patternfly/chatbot/dist/css/main.css';
|
|
54
|
+
|
|
55
|
+
const footnoteProps = {
|
|
56
|
+
label: 'ChatBot uses AI. Check for mistakes.',
|
|
57
|
+
popover: {
|
|
58
|
+
title: 'Verify accuracy',
|
|
59
|
+
description: `While ChatBot strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
|
|
60
|
+
bannerImage: {
|
|
61
|
+
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
|
|
62
|
+
alt: 'Example image for footnote popover'
|
|
63
|
+
},
|
|
64
|
+
cta: {
|
|
65
|
+
label: 'Got it',
|
|
66
|
+
onClick: () => {
|
|
67
|
+
alert('Do something!');
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
link: {
|
|
71
|
+
label: 'Learn more',
|
|
72
|
+
url: 'https://www.redhat.com/'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const markdown = `A paragraph with *emphasis* and **strong importance**.`;
|
|
78
|
+
|
|
79
|
+
const date = new Date();
|
|
80
|
+
|
|
81
|
+
const initialMessages: MessageProps[] = [
|
|
82
|
+
{
|
|
83
|
+
id: '1',
|
|
84
|
+
role: 'user',
|
|
85
|
+
content: 'Hello, can you give me an example of what you can do?',
|
|
86
|
+
name: 'User',
|
|
87
|
+
avatar: userAvatar,
|
|
88
|
+
timestamp: date.toLocaleString(),
|
|
89
|
+
avatarProps: { isBordered: true }
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: '2',
|
|
93
|
+
role: 'bot',
|
|
94
|
+
content: markdown,
|
|
95
|
+
name: 'Bot',
|
|
96
|
+
avatar: patternflyAvatar,
|
|
97
|
+
timestamp: date.toLocaleString(),
|
|
98
|
+
actions: {
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
positive: { onClick: () => console.log('Good response') },
|
|
101
|
+
// eslint-disable-next-line no-console
|
|
102
|
+
negative: { onClick: () => console.log('Bad response') },
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
copy: { onClick: () => console.log('Copy') },
|
|
105
|
+
// eslint-disable-next-line no-console
|
|
106
|
+
download: { onClick: () => console.log('Download') },
|
|
107
|
+
// eslint-disable-next-line no-console
|
|
108
|
+
listen: { onClick: () => console.log('Listen') }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
const welcomePrompts = [
|
|
114
|
+
{
|
|
115
|
+
title: 'Topic 1',
|
|
116
|
+
message: 'Helpful prompt for Topic 1'
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
title: 'Topic 2',
|
|
120
|
+
message: 'Helpful prompt for Topic 2'
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
const initialConversations = {
|
|
125
|
+
Today: [{ id: '1', text: 'Hello, can you give me an example of what you can do?' }],
|
|
126
|
+
'This month': [
|
|
127
|
+
{
|
|
128
|
+
id: '2',
|
|
129
|
+
text: 'Enterprise Linux installation and setup'
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const ChatbotDisplayModeDemo: FunctionComponent = () => {
|
|
135
|
+
const [messages, setMessages] = useState<MessageProps[]>(initialMessages);
|
|
136
|
+
const [selectedModel, setSelectedModel] = useState('Granite 7B');
|
|
137
|
+
const [isSendButtonDisabled, setIsSendButtonDisabled] = useState(false);
|
|
138
|
+
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
|
139
|
+
const [conversations, setConversations] = useState<Conversation[] | { [key: string]: Conversation[] }>(
|
|
140
|
+
initialConversations
|
|
141
|
+
);
|
|
142
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
|
143
|
+
const [announcement, setAnnouncement] = useState<string>();
|
|
144
|
+
const scrollToBottomRef = useRef<HTMLDivElement>(null);
|
|
145
|
+
const historyRef = useRef<HTMLButtonElement>(null);
|
|
146
|
+
const drawerRef = useRef<HTMLDivElement>();
|
|
147
|
+
const [chatbotVisible, setChatbotVisible] = useState<boolean>(true);
|
|
148
|
+
const toggleRef = useRef<HTMLButtonElement>(null);
|
|
149
|
+
const chatbotRef = useRef<HTMLDivElement>(null);
|
|
150
|
+
const [shouldFocusOptions, setShouldFocusOptions] = useState(false);
|
|
151
|
+
|
|
152
|
+
const [displayMode, setDisplayMode] = useState<ChatbotDisplayMode>(ChatbotDisplayMode.default);
|
|
153
|
+
|
|
154
|
+
const isDrawerPanelExpanded = displayMode === ChatbotDisplayMode.drawer;
|
|
155
|
+
|
|
156
|
+
const onExpand = () => {
|
|
157
|
+
drawerRef.current && drawerRef.current.focus();
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (messages.length > 2) {
|
|
162
|
+
scrollToBottomRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
163
|
+
}
|
|
164
|
+
}, [messages]);
|
|
165
|
+
|
|
166
|
+
// Focus options dropdown after display mode changes
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
if (shouldFocusOptions) {
|
|
169
|
+
// Use a more reliable timeout to ensure DOM has updated
|
|
170
|
+
const timeoutId = setTimeout(() => {
|
|
171
|
+
// Find the options dropdown button via CSS selector since ref forwarding isn't supported
|
|
172
|
+
const optionsButton = document.querySelector('.pf-chatbot__button--toggle-options');
|
|
173
|
+
if (optionsButton instanceof HTMLElement) {
|
|
174
|
+
optionsButton.focus();
|
|
175
|
+
}
|
|
176
|
+
setShouldFocusOptions(false);
|
|
177
|
+
}, 100);
|
|
178
|
+
|
|
179
|
+
return () => clearTimeout(timeoutId);
|
|
180
|
+
}
|
|
181
|
+
}, [displayMode, shouldFocusOptions]);
|
|
182
|
+
|
|
183
|
+
const onSelectModel = (_event: MouseEvent<Element, MouseEvent> | undefined, value: string | number | undefined) => {
|
|
184
|
+
setSelectedModel(value as string);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const onSelectDisplayMode = (
|
|
188
|
+
_event: MouseEvent<Element, MouseEvent> | undefined,
|
|
189
|
+
value: string | number | undefined
|
|
190
|
+
) => {
|
|
191
|
+
setDisplayMode(value as ChatbotDisplayMode);
|
|
192
|
+
// Flag to focus options dropdown after render
|
|
193
|
+
setShouldFocusOptions(true);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const generateId = () => {
|
|
197
|
+
const id = Date.now() + Math.random();
|
|
198
|
+
return id.toString();
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const handleSend = (message: string) => {
|
|
202
|
+
setIsSendButtonDisabled(true);
|
|
203
|
+
const newMessages: MessageProps[] = [...messages];
|
|
204
|
+
const date = new Date();
|
|
205
|
+
newMessages.push({
|
|
206
|
+
id: generateId(),
|
|
207
|
+
role: 'user',
|
|
208
|
+
content: message,
|
|
209
|
+
name: 'User',
|
|
210
|
+
avatar: userAvatar,
|
|
211
|
+
timestamp: date.toLocaleString(),
|
|
212
|
+
avatarProps: { isBordered: true }
|
|
213
|
+
});
|
|
214
|
+
newMessages.push({
|
|
215
|
+
id: generateId(),
|
|
216
|
+
role: 'bot',
|
|
217
|
+
content: 'API response goes here',
|
|
218
|
+
name: 'Bot',
|
|
219
|
+
avatar: patternflyAvatar,
|
|
220
|
+
isLoading: true,
|
|
221
|
+
timestamp: date.toLocaleString()
|
|
222
|
+
});
|
|
223
|
+
setMessages(newMessages);
|
|
224
|
+
setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`);
|
|
225
|
+
|
|
226
|
+
setTimeout(() => {
|
|
227
|
+
const loadedMessages: MessageProps[] = [...newMessages];
|
|
228
|
+
loadedMessages.pop();
|
|
229
|
+
loadedMessages.push({
|
|
230
|
+
id: generateId(),
|
|
231
|
+
role: 'bot',
|
|
232
|
+
content: 'API response goes here',
|
|
233
|
+
name: 'Bot',
|
|
234
|
+
avatar: patternflyAvatar,
|
|
235
|
+
isLoading: false,
|
|
236
|
+
actions: {
|
|
237
|
+
// eslint-disable-next-line no-console
|
|
238
|
+
positive: { onClick: () => console.log('Good response') },
|
|
239
|
+
// eslint-disable-next-line no-console
|
|
240
|
+
negative: { onClick: () => console.log('Bad response') },
|
|
241
|
+
// eslint-disable-next-line no-console
|
|
242
|
+
copy: { onClick: () => console.log('Copy') },
|
|
243
|
+
// eslint-disable-next-line no-console
|
|
244
|
+
download: { onClick: () => console.log('Download') },
|
|
245
|
+
// eslint-disable-next-line no-console
|
|
246
|
+
listen: { onClick: () => console.log('Listen') }
|
|
247
|
+
},
|
|
248
|
+
timestamp: date.toLocaleString()
|
|
249
|
+
});
|
|
250
|
+
setMessages(loadedMessages);
|
|
251
|
+
setAnnouncement(`Message from Bot: API response goes here`);
|
|
252
|
+
setIsSendButtonDisabled(false);
|
|
253
|
+
}, 2000);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const findMatchingItems = (targetValue: string) => {
|
|
257
|
+
let filteredConversations = Object.entries(initialConversations).reduce((acc, [key, items]) => {
|
|
258
|
+
const filteredItems = items.filter((item) => item.text.toLowerCase().includes(targetValue.toLowerCase()));
|
|
259
|
+
if (filteredItems.length > 0) {
|
|
260
|
+
acc[key] = filteredItems;
|
|
261
|
+
}
|
|
262
|
+
return acc;
|
|
263
|
+
}, {});
|
|
264
|
+
|
|
265
|
+
if (Object.keys(filteredConversations).length === 0) {
|
|
266
|
+
filteredConversations = [{ id: '13', noIcon: true, text: 'No results found' }];
|
|
267
|
+
}
|
|
268
|
+
return filteredConversations;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const iconLogo = (
|
|
272
|
+
<>
|
|
273
|
+
<Brand className="show-light" src={PFIconLogoColor} alt="PatternFly" />
|
|
274
|
+
<Brand className="show-dark" src={PFIconLogoReverse} alt="PatternFly" />
|
|
275
|
+
</>
|
|
276
|
+
);
|
|
277
|
+
const masthead = (
|
|
278
|
+
<Masthead>
|
|
279
|
+
<MastheadMain>
|
|
280
|
+
<MastheadToggle>
|
|
281
|
+
<PageToggleButton
|
|
282
|
+
variant="plain"
|
|
283
|
+
aria-label="Global navigation"
|
|
284
|
+
isSidebarOpen={isSidebarOpen}
|
|
285
|
+
onSidebarToggle={() => setIsSidebarOpen(!isSidebarOpen)}
|
|
286
|
+
id="fill-nav-toggle"
|
|
287
|
+
>
|
|
288
|
+
<BarsIcon />
|
|
289
|
+
</PageToggleButton>
|
|
290
|
+
</MastheadToggle>
|
|
291
|
+
<MastheadBrand>
|
|
292
|
+
<MastheadLogo href="https://patternfly.org" target="_blank">
|
|
293
|
+
Logo
|
|
294
|
+
</MastheadLogo>
|
|
295
|
+
</MastheadBrand>
|
|
296
|
+
</MastheadMain>
|
|
297
|
+
</Masthead>
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
const sidebar = (
|
|
301
|
+
<PageSidebar isSidebarOpen={isSidebarOpen} id="fill-sidebar">
|
|
302
|
+
<PageSidebarBody>Navigation</PageSidebarBody>
|
|
303
|
+
</PageSidebar>
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
const skipToChatbot = (e: MouseEvent) => {
|
|
307
|
+
e.preventDefault();
|
|
308
|
+
/* eslint-disable indent */
|
|
309
|
+
switch (displayMode) {
|
|
310
|
+
case ChatbotDisplayMode.default:
|
|
311
|
+
if (!chatbotVisible && toggleRef.current) {
|
|
312
|
+
toggleRef.current.focus();
|
|
313
|
+
}
|
|
314
|
+
if (chatbotVisible && chatbotRef.current) {
|
|
315
|
+
chatbotRef.current.focus();
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
default:
|
|
319
|
+
if (historyRef.current) {
|
|
320
|
+
historyRef.current.focus();
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
/* eslint-enable indent */
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const skipToContent = (
|
|
328
|
+
<SkipToContent href="#" onClick={skipToChatbot}>
|
|
329
|
+
Skip to chatbot
|
|
330
|
+
</SkipToContent>
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
const handleChatbotVisibilityDrawer = () => {
|
|
334
|
+
setChatbotVisible(!chatbotVisible);
|
|
335
|
+
setDisplayMode(ChatbotDisplayMode.default);
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const chatbotComponent = (
|
|
339
|
+
<Chatbot isVisible={chatbotVisible} displayMode={displayMode} ref={chatbotRef}>
|
|
340
|
+
<ChatbotConversationHistoryNav
|
|
341
|
+
displayMode={displayMode}
|
|
342
|
+
onDrawerToggle={() => {
|
|
343
|
+
setIsDrawerOpen(!isDrawerOpen);
|
|
344
|
+
setConversations(initialConversations);
|
|
345
|
+
}}
|
|
346
|
+
isDrawerOpen={isDrawerOpen}
|
|
347
|
+
setIsDrawerOpen={setIsDrawerOpen}
|
|
348
|
+
activeItemId="1"
|
|
349
|
+
conversations={conversations}
|
|
350
|
+
onNewChat={() => {
|
|
351
|
+
setIsDrawerOpen(!isDrawerOpen);
|
|
352
|
+
setMessages([]);
|
|
353
|
+
setConversations(initialConversations);
|
|
354
|
+
}}
|
|
355
|
+
handleTextInputChange={(value: string) => {
|
|
356
|
+
if (value === '') {
|
|
357
|
+
setConversations(initialConversations);
|
|
358
|
+
}
|
|
359
|
+
const newConversations: { [key: string]: Conversation[] } = findMatchingItems(value);
|
|
360
|
+
setConversations(newConversations);
|
|
361
|
+
}}
|
|
362
|
+
drawerContent={
|
|
363
|
+
<>
|
|
364
|
+
<ChatbotHeader>
|
|
365
|
+
<ChatbotHeaderMain>
|
|
366
|
+
<ChatbotHeaderMenu
|
|
367
|
+
ref={historyRef}
|
|
368
|
+
aria-expanded={isDrawerOpen}
|
|
369
|
+
onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)}
|
|
370
|
+
/>
|
|
371
|
+
<ChatbotHeaderTitle>{iconLogo}</ChatbotHeaderTitle>
|
|
372
|
+
</ChatbotHeaderMain>
|
|
373
|
+
<ChatbotHeaderActions>
|
|
374
|
+
<ChatbotHeaderSelectorDropdown value={selectedModel} onSelect={onSelectModel}>
|
|
375
|
+
<DropdownList>
|
|
376
|
+
<DropdownItem value="Granite 7B" key="granite">
|
|
377
|
+
Granite 7B
|
|
378
|
+
</DropdownItem>
|
|
379
|
+
<DropdownItem value="Llama 3.0" key="llama">
|
|
380
|
+
Llama 3.0
|
|
381
|
+
</DropdownItem>
|
|
382
|
+
</DropdownList>
|
|
383
|
+
</ChatbotHeaderSelectorDropdown>
|
|
384
|
+
<ChatbotHeaderOptionsDropdown onSelect={onSelectDisplayMode}>
|
|
385
|
+
<DropdownGroup label="Display mode">
|
|
386
|
+
<DropdownList>
|
|
387
|
+
<DropdownItem
|
|
388
|
+
value={ChatbotDisplayMode.default}
|
|
389
|
+
key="switchDisplayOverlay"
|
|
390
|
+
icon={<OutlinedWindowRestoreIcon aria-hidden />}
|
|
391
|
+
isSelected={displayMode === ChatbotDisplayMode.default}
|
|
392
|
+
>
|
|
393
|
+
<span>Overlay</span>
|
|
394
|
+
</DropdownItem>
|
|
395
|
+
<DropdownItem
|
|
396
|
+
value={ChatbotDisplayMode.drawer}
|
|
397
|
+
key="switchDisplayDock"
|
|
398
|
+
icon={<OpenDrawerRightIcon aria-hidden />}
|
|
399
|
+
isSelected={displayMode === ChatbotDisplayMode.drawer}
|
|
400
|
+
>
|
|
401
|
+
<span>Drawer</span>
|
|
402
|
+
</DropdownItem>
|
|
403
|
+
<DropdownItem
|
|
404
|
+
value={ChatbotDisplayMode.fullscreen}
|
|
405
|
+
key="switchDisplayFullscreen"
|
|
406
|
+
icon={<ExpandIcon aria-hidden />}
|
|
407
|
+
isSelected={displayMode === ChatbotDisplayMode.fullscreen}
|
|
408
|
+
>
|
|
409
|
+
<span>Fullscreen</span>
|
|
410
|
+
</DropdownItem>
|
|
411
|
+
</DropdownList>
|
|
412
|
+
</DropdownGroup>
|
|
413
|
+
</ChatbotHeaderOptionsDropdown>
|
|
414
|
+
{(displayMode === ChatbotDisplayMode.drawer || displayMode === ChatbotDisplayMode.fullscreen) && (
|
|
415
|
+
<ChatbotHeaderCloseButton onClick={handleChatbotVisibilityDrawer} />
|
|
416
|
+
)}
|
|
417
|
+
</ChatbotHeaderActions>
|
|
418
|
+
</ChatbotHeader>
|
|
419
|
+
<ChatbotContent>
|
|
420
|
+
<MessageBox announcement={announcement}>
|
|
421
|
+
<ChatbotWelcomePrompt
|
|
422
|
+
title="Hello, Chatbot User"
|
|
423
|
+
description="How may I help you today?"
|
|
424
|
+
prompts={welcomePrompts}
|
|
425
|
+
/>
|
|
426
|
+
{messages.map((message, index) => {
|
|
427
|
+
if (index === messages.length - 1) {
|
|
428
|
+
return (
|
|
429
|
+
<React.Fragment key={message.id}>
|
|
430
|
+
<div ref={scrollToBottomRef}></div>
|
|
431
|
+
<Message {...message} />
|
|
432
|
+
</React.Fragment>
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
return <Message key={message.id} {...message} />;
|
|
436
|
+
})}
|
|
437
|
+
</MessageBox>
|
|
438
|
+
</ChatbotContent>
|
|
439
|
+
<ChatbotFooter>
|
|
440
|
+
<MessageBar onSendMessage={handleSend} hasMicrophoneButton isSendButtonDisabled={isSendButtonDisabled} />
|
|
441
|
+
<ChatbotFootnote {...footnoteProps} />
|
|
442
|
+
</ChatbotFooter>
|
|
443
|
+
</>
|
|
444
|
+
}
|
|
445
|
+
/>
|
|
446
|
+
</Chatbot>
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const chatbotToggle =
|
|
450
|
+
displayMode === ChatbotDisplayMode.default ? (
|
|
451
|
+
<ChatbotToggle
|
|
452
|
+
tooltipLabel="Chatbot"
|
|
453
|
+
isChatbotVisible={chatbotVisible}
|
|
454
|
+
onToggleChatbot={() => {
|
|
455
|
+
setChatbotVisible(!chatbotVisible);
|
|
456
|
+
}}
|
|
457
|
+
id="chatbot-toggle"
|
|
458
|
+
ref={toggleRef}
|
|
459
|
+
/>
|
|
460
|
+
) : null;
|
|
461
|
+
|
|
462
|
+
const panelContent = <DrawerPanelContent>{chatbotComponent}</DrawerPanelContent>;
|
|
463
|
+
|
|
464
|
+
const pageContent = (
|
|
465
|
+
<Page skipToContent={skipToContent} masthead={masthead} sidebar={sidebar} isContentFilled>
|
|
466
|
+
{displayMode === ChatbotDisplayMode.default && chatbotToggle}
|
|
467
|
+
</Page>
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
if (displayMode === ChatbotDisplayMode.drawer) {
|
|
471
|
+
return (
|
|
472
|
+
<Drawer isExpanded={isDrawerPanelExpanded} isInline onExpand={onExpand}>
|
|
473
|
+
<DrawerContent panelContent={panelContent}>
|
|
474
|
+
<DrawerContentBody>{pageContent}</DrawerContentBody>
|
|
475
|
+
</DrawerContent>
|
|
476
|
+
</Drawer>
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return (
|
|
481
|
+
<>
|
|
482
|
+
{pageContent}
|
|
483
|
+
{chatbotComponent}
|
|
484
|
+
</>
|
|
485
|
+
);
|
|
486
|
+
};
|