@patternfly/chatbot 2.2.0-prerelease.1 → 2.2.0-prerelease.11
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 +19 -1
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +11 -11
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +39 -3
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/CodeModal/CodeModal.js +2 -12
- package/dist/cjs/Compare/Compare.d.ts +17 -0
- package/dist/cjs/Compare/Compare.js +50 -0
- package/dist/cjs/Compare/Compare.test.d.ts +1 -0
- package/dist/cjs/Compare/Compare.test.js +20 -0
- package/dist/cjs/Compare/index.d.ts +2 -0
- package/dist/cjs/Compare/index.js +23 -0
- package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
- package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
- package/dist/cjs/Message/Message.d.ts +16 -6
- package/dist/cjs/Message/Message.js +6 -6
- package/dist/cjs/Message/Message.test.js +51 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +15 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.js +33 -0
- package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
- package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
- package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
- package/dist/cjs/Message/QuickStarts/types.js +17 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
- package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
- package/dist/cjs/Settings/SettingsForm.js +27 -0
- package/dist/cjs/Settings/index.d.ts +2 -0
- package/dist/cjs/Settings/index.js +23 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +34 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.js +49 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.test.d.ts +1 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.test.js +79 -0
- package/dist/cjs/TermsOfUse/index.d.ts +2 -0
- package/dist/cjs/TermsOfUse/index.js +23 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +10 -1
- package/dist/css/main.css +244 -18
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/Compare/package.json +1 -0
- package/dist/dynamic/Settings/package.json +1 -0
- package/dist/dynamic/TermsOfUse/package.json +1 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +19 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +11 -11
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +39 -3
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/CodeModal/CodeModal.js +2 -12
- package/dist/esm/Compare/Compare.d.ts +17 -0
- package/dist/esm/Compare/Compare.js +43 -0
- package/dist/esm/Compare/Compare.test.d.ts +1 -0
- package/dist/esm/Compare/Compare.test.js +15 -0
- package/dist/esm/Compare/index.d.ts +2 -0
- package/dist/esm/Compare/index.js +2 -0
- package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
- package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
- package/dist/esm/Message/Message.d.ts +16 -6
- package/dist/esm/Message/Message.js +7 -7
- package/dist/esm/Message/Message.test.js +51 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +15 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.js +26 -0
- package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
- package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
- package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
- package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
- package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
- package/dist/esm/Message/QuickStarts/types.js +14 -0
- package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/esm/ResponseActions/ResponseActions.js +26 -9
- package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/esm/Settings/SettingsForm.d.ts +13 -0
- package/dist/esm/Settings/SettingsForm.js +20 -0
- package/dist/esm/Settings/index.d.ts +2 -0
- package/dist/esm/Settings/index.js +2 -0
- package/dist/esm/TermsOfUse/TermsOfUse.d.ts +34 -0
- package/dist/esm/TermsOfUse/TermsOfUse.js +42 -0
- package/dist/esm/TermsOfUse/TermsOfUse.test.d.ts +1 -0
- package/dist/esm/TermsOfUse/TermsOfUse.test.js +74 -0
- package/dist/esm/TermsOfUse/index.d.ts +2 -0
- package/dist/esm/TermsOfUse/index.js +2 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +6 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -13
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +26 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerNavigation.tsx +67 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerResizable.tsx +94 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +78 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/PF-TermsAndConditionsHeader.svg +148 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUse.tsx +147 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +54 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +26 -3
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +20 -19
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx +206 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +112 -3
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +46 -9
- package/src/ChatbotFooter/ChatbotFooter.scss +2 -1
- package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/CodeModal/CodeModal.scss +8 -0
- package/src/CodeModal/CodeModal.tsx +2 -13
- package/src/Compare/Compare.scss +72 -0
- package/src/Compare/Compare.test.tsx +31 -0
- package/src/Compare/Compare.tsx +98 -0
- package/src/Compare/index.ts +2 -0
- package/src/FileDropZone/__snapshots__/FileDropZone.test.tsx.snap +1 -1
- package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
- package/src/Message/Message.scss +0 -14
- package/src/Message/Message.test.tsx +76 -0
- package/src/Message/Message.tsx +35 -26
- package/src/Message/QuickResponse/QuickResponse.scss +33 -0
- package/src/Message/QuickResponse/QuickResponse.tsx +50 -0
- package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
- package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
- package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
- package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
- package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
- package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
- package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
- package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
- package/src/Message/QuickStarts/types.ts +154 -0
- package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
- package/src/ResponseActions/ResponseActionButton.tsx +46 -27
- package/src/ResponseActions/ResponseActions.scss +10 -8
- package/src/ResponseActions/ResponseActions.test.tsx +103 -5
- package/src/ResponseActions/ResponseActions.tsx +54 -7
- package/src/Settings/Settings.scss +34 -0
- package/src/Settings/SettingsForm.tsx +25 -0
- package/src/Settings/index.ts +3 -0
- package/src/TermsOfUse/TermsOfUse.scss +66 -0
- package/src/TermsOfUse/TermsOfUse.test.tsx +138 -0
- package/src/TermsOfUse/TermsOfUse.tsx +117 -0
- package/src/TermsOfUse/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/main.scss +5 -0
@@ -42,10 +42,10 @@ import userAvatar from '../Messages/user_avatar.svg';
|
|
42
42
|
import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
|
43
43
|
|
44
44
|
const footnoteProps = {
|
45
|
-
label: '
|
45
|
+
label: 'ChatBot uses AI. Check for mistakes.',
|
46
46
|
popover: {
|
47
47
|
title: 'Verify accuracy',
|
48
|
-
description: `While
|
48
|
+
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.`,
|
49
49
|
bannerImage: {
|
50
50
|
src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',
|
51
51
|
alt: 'Example image for footnote popover'
|
package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
import {
|
4
|
+
Page,
|
5
|
+
Masthead,
|
6
|
+
MastheadMain,
|
7
|
+
MastheadBrand,
|
8
|
+
MastheadLogo,
|
9
|
+
PageSidebarBody,
|
10
|
+
PageSidebar,
|
11
|
+
MastheadToggle,
|
12
|
+
PageToggleButton
|
13
|
+
} from '@patternfly/react-core';
|
14
|
+
import Chatbot, { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot';
|
15
|
+
import ChatbotContent from '@patternfly/chatbot/dist/dynamic/ChatbotContent';
|
16
|
+
import ChatbotWelcomePrompt from '@patternfly/chatbot/dist/dynamic/ChatbotWelcomePrompt';
|
17
|
+
import ChatbotFooter from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';
|
18
|
+
import MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar';
|
19
|
+
import MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox';
|
20
|
+
import Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message';
|
21
|
+
import ChatbotHeader, { ChatbotHeaderMain } from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
|
22
|
+
import Compare from '@patternfly/chatbot/dist/dynamic/Compare';
|
23
|
+
import { BarsIcon } from '@patternfly/react-icons';
|
24
|
+
import userAvatar from '../Messages/user_avatar.svg';
|
25
|
+
import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
|
26
|
+
|
27
|
+
export const CompareChild = ({ name, input, hasNewInput, setIsSendButtonDisabled }) => {
|
28
|
+
const [messages, setMessages] = React.useState<MessageProps[]>([]);
|
29
|
+
const [announcement, setAnnouncement] = React.useState<string>();
|
30
|
+
const scrollToBottomRef = React.useRef<HTMLDivElement>(null);
|
31
|
+
const displayMode = ChatbotDisplayMode.embedded;
|
32
|
+
|
33
|
+
// you will likely want to come up with your own unique id function; this is for demo purposes only
|
34
|
+
const generateId = () => {
|
35
|
+
const id = Date.now() + Math.random();
|
36
|
+
return id.toString();
|
37
|
+
};
|
38
|
+
|
39
|
+
const handleSend = (input: string) => {
|
40
|
+
const date = new Date();
|
41
|
+
const newMessages: MessageProps[] = [];
|
42
|
+
messages.forEach((message) => newMessages.push(message));
|
43
|
+
newMessages.push({
|
44
|
+
avatar: userAvatar,
|
45
|
+
avatarProps: { isBordered: true },
|
46
|
+
id: generateId(),
|
47
|
+
name: 'You',
|
48
|
+
role: 'user',
|
49
|
+
content: input,
|
50
|
+
timestamp: `${date?.toLocaleDateString()} ${date?.toLocaleTimeString()}`
|
51
|
+
});
|
52
|
+
newMessages.push({
|
53
|
+
avatar: patternflyAvatar,
|
54
|
+
id: generateId(),
|
55
|
+
name,
|
56
|
+
role: 'bot',
|
57
|
+
timestamp: `${date?.toLocaleDateString()} ${date?.toLocaleTimeString()}`,
|
58
|
+
isLoading: true
|
59
|
+
});
|
60
|
+
setMessages(newMessages);
|
61
|
+
// make announcement to assistive devices that new messages have been added
|
62
|
+
setAnnouncement(`Message from You: ${input}. Message from ${name} is loading.`);
|
63
|
+
|
64
|
+
// this is for demo purposes only; in a real situation, there would be an API response we would wait for
|
65
|
+
setTimeout(() => {
|
66
|
+
const loadedMessages: MessageProps[] = [];
|
67
|
+
// we can't use structuredClone since messages contains functions, but we can't mutate
|
68
|
+
// items that are going into state or the UI won't update correctly
|
69
|
+
newMessages.forEach((message) => loadedMessages.push(message));
|
70
|
+
loadedMessages.pop();
|
71
|
+
loadedMessages.push({
|
72
|
+
id: generateId(),
|
73
|
+
role: 'bot',
|
74
|
+
content: `API response from ${name} goes here`,
|
75
|
+
name,
|
76
|
+
avatar: patternflyAvatar,
|
77
|
+
isLoading: false,
|
78
|
+
actions: {
|
79
|
+
// eslint-disable-next-line no-console
|
80
|
+
positive: { onClick: () => console.log('Good response') },
|
81
|
+
// eslint-disable-next-line no-console
|
82
|
+
negative: { onClick: () => console.log('Bad response') },
|
83
|
+
// eslint-disable-next-line no-console
|
84
|
+
copy: { onClick: () => console.log('Copy') },
|
85
|
+
// eslint-disable-next-line no-console
|
86
|
+
share: { onClick: () => console.log('Share') },
|
87
|
+
// eslint-disable-next-line no-console
|
88
|
+
listen: { onClick: () => console.log('Listen') }
|
89
|
+
},
|
90
|
+
timestamp: date.toLocaleString()
|
91
|
+
});
|
92
|
+
setMessages(loadedMessages);
|
93
|
+
// make announcement to assistive devices that new message has loaded
|
94
|
+
setAnnouncement(`Message from ${name}: API response goes here`);
|
95
|
+
setIsSendButtonDisabled(false);
|
96
|
+
}, 5000);
|
97
|
+
};
|
98
|
+
|
99
|
+
React.useEffect(() => {
|
100
|
+
if (input) {
|
101
|
+
handleSend(input);
|
102
|
+
}
|
103
|
+
}, [hasNewInput]);
|
104
|
+
|
105
|
+
// Auto-scrolls to the latest message
|
106
|
+
React.useEffect(() => {
|
107
|
+
// don't scroll the first load, but scroll if there's a current stream or a new source has popped up
|
108
|
+
if (messages.length > 0) {
|
109
|
+
scrollToBottomRef.current?.scrollIntoView();
|
110
|
+
}
|
111
|
+
}, [messages]);
|
112
|
+
|
113
|
+
return (
|
114
|
+
<Chatbot displayMode={displayMode}>
|
115
|
+
<ChatbotHeader>
|
116
|
+
<ChatbotHeaderMain>{name}</ChatbotHeaderMain>
|
117
|
+
</ChatbotHeader>
|
118
|
+
<ChatbotContent>
|
119
|
+
<MessageBox ariaLabel={`Scrollable message log for ${name}`} announcement={announcement}>
|
120
|
+
<ChatbotWelcomePrompt title="Hello, Chatbot User" description="How may I help you today?" />
|
121
|
+
{messages.map((message) => (
|
122
|
+
<Message key={message.id} {...message} />
|
123
|
+
))}
|
124
|
+
<div ref={scrollToBottomRef}></div>
|
125
|
+
</MessageBox>
|
126
|
+
</ChatbotContent>
|
127
|
+
</Chatbot>
|
128
|
+
);
|
129
|
+
};
|
130
|
+
|
131
|
+
export const EmbeddedComparisonChatbotDemo: React.FunctionComponent = () => {
|
132
|
+
const [input, setInput] = React.useState<string>();
|
133
|
+
const [hasNewInput, setHasNewInput] = React.useState(false);
|
134
|
+
const [isSidebarOpen, setIsSidebarOpen] = React.useState(false);
|
135
|
+
const [isSendButtonDisabled, setIsSendButtonDisabled] = React.useState(false);
|
136
|
+
|
137
|
+
const handleSend = (value: string) => {
|
138
|
+
setInput(value);
|
139
|
+
setHasNewInput(!hasNewInput);
|
140
|
+
setIsSendButtonDisabled(true);
|
141
|
+
};
|
142
|
+
|
143
|
+
const masthead = (
|
144
|
+
<Masthead>
|
145
|
+
<MastheadMain>
|
146
|
+
<MastheadToggle>
|
147
|
+
<PageToggleButton
|
148
|
+
variant="plain"
|
149
|
+
aria-label="Global navigation"
|
150
|
+
isSidebarOpen={isSidebarOpen}
|
151
|
+
onSidebarToggle={() => setIsSidebarOpen(!isSidebarOpen)}
|
152
|
+
id="fill-nav-toggle"
|
153
|
+
>
|
154
|
+
<BarsIcon />
|
155
|
+
</PageToggleButton>
|
156
|
+
</MastheadToggle>
|
157
|
+
<MastheadBrand>
|
158
|
+
<MastheadLogo href="https://patternfly.org" target="_blank">
|
159
|
+
Logo
|
160
|
+
</MastheadLogo>
|
161
|
+
</MastheadBrand>
|
162
|
+
</MastheadMain>
|
163
|
+
</Masthead>
|
164
|
+
);
|
165
|
+
|
166
|
+
const sidebar = (
|
167
|
+
<PageSidebar isSidebarOpen={isSidebarOpen} id="fill-sidebar">
|
168
|
+
<PageSidebarBody>Navigation</PageSidebarBody>
|
169
|
+
</PageSidebar>
|
170
|
+
);
|
171
|
+
|
172
|
+
return (
|
173
|
+
<Page masthead={masthead} sidebar={sidebar} isContentFilled>
|
174
|
+
<div className="pf-chatbot__compare-container">
|
175
|
+
<Compare
|
176
|
+
firstChild={
|
177
|
+
<CompareChild
|
178
|
+
input={input}
|
179
|
+
hasNewInput={hasNewInput}
|
180
|
+
name="ChatBot 1"
|
181
|
+
setIsSendButtonDisabled={setIsSendButtonDisabled}
|
182
|
+
/>
|
183
|
+
}
|
184
|
+
secondChild={
|
185
|
+
<CompareChild
|
186
|
+
input={input}
|
187
|
+
hasNewInput={hasNewInput}
|
188
|
+
name="ChatBot 2"
|
189
|
+
setIsSendButtonDisabled={setIsSendButtonDisabled}
|
190
|
+
/>
|
191
|
+
}
|
192
|
+
firstChildDisplayName="ChatBot 1"
|
193
|
+
secondChildDisplayName="ChatBot 2"
|
194
|
+
/>
|
195
|
+
<ChatbotFooter>
|
196
|
+
<MessageBar
|
197
|
+
onSendMessage={handleSend}
|
198
|
+
hasAttachButton={false}
|
199
|
+
alwayShowSendButton
|
200
|
+
isSendButtonDisabled={isSendButtonDisabled}
|
201
|
+
/>
|
202
|
+
</ChatbotFooter>
|
203
|
+
</div>
|
204
|
+
</Page>
|
205
|
+
);
|
206
|
+
};
|
@@ -44,10 +44,23 @@
|
|
44
44
|
color: var(--pf-t--global--text--color--regular);
|
45
45
|
font-size: var(--pf-t--global--font--size--body--lg);
|
46
46
|
font-weight: var(--pf-t--global--font--weight--body--default);
|
47
|
+
border-radius: var(--pf-t--global--border--radius--small);
|
48
|
+
}
|
49
|
+
// allows focus state to have border radius
|
50
|
+
.pf-v6-c-menu__list-item.pf-chatbot__menu-item {
|
51
|
+
overflow: hidden;
|
47
52
|
}
|
48
53
|
.pf-chatbot__history-actions {
|
49
54
|
transform: rotate(90deg);
|
50
55
|
}
|
56
|
+
|
57
|
+
.pf-chatbot__menu-item--active {
|
58
|
+
background-color: var(--pf-t--global--background--color--action--plain--clicked);
|
59
|
+
}
|
60
|
+
|
61
|
+
button.pf-chatbot__menu-item--active {
|
62
|
+
background-color: initial;
|
63
|
+
}
|
51
64
|
}
|
52
65
|
|
53
66
|
// Chatbot Header - Drawer
|
@@ -105,6 +118,7 @@
|
|
105
118
|
border-radius: var(--pf-t--global--border--radius--pill);
|
106
119
|
justify-content: center;
|
107
120
|
align-items: center;
|
121
|
+
border-radius: var(--pf-t--global--border--radius--small);
|
108
122
|
}
|
109
123
|
}
|
110
124
|
|
@@ -11,7 +11,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
11
11
|
const initialConversations: Conversation[] = [
|
12
12
|
{
|
13
13
|
id: '1',
|
14
|
-
text: '
|
14
|
+
text: 'ChatBot documentation'
|
15
15
|
}
|
16
16
|
];
|
17
17
|
|
@@ -25,7 +25,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
25
25
|
conversations={initialConversations}
|
26
26
|
/>
|
27
27
|
);
|
28
|
-
expect(screen.queryByText('
|
28
|
+
expect(screen.queryByText('ChatBot documentation')).toBeInTheDocument();
|
29
29
|
});
|
30
30
|
|
31
31
|
it('should display the conversations for grouped conversations', () => {
|
@@ -120,7 +120,116 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
120
120
|
});
|
121
121
|
|
122
122
|
waitFor(() => {
|
123
|
-
expect(screen.queryByText('
|
123
|
+
expect(screen.queryByText('ChatBot documentation')).not.toBeInTheDocument();
|
124
124
|
});
|
125
125
|
});
|
126
|
+
|
127
|
+
it('should be resizable', () => {
|
128
|
+
render(
|
129
|
+
<ChatbotConversationHistoryNav
|
130
|
+
onDrawerToggle={onDrawerToggle}
|
131
|
+
isDrawerOpen={true}
|
132
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
133
|
+
setIsDrawerOpen={jest.fn()}
|
134
|
+
conversations={initialConversations}
|
135
|
+
drawerPanelContentProps={{ isResizable: true, minSize: '200px' }}
|
136
|
+
/>
|
137
|
+
);
|
138
|
+
expect(screen.getByRole('dialog', { name: /Resize/i })).toBeTruthy();
|
139
|
+
expect(screen.getByRole('separator', { name: /Resize/i })).toBeTruthy();
|
140
|
+
expect(screen.getByRole('dialog', { name: /Resize/i })).toHaveAttribute(
|
141
|
+
'style',
|
142
|
+
'--pf-v6-c-drawer__panel--md--FlexBasis: 384px; --pf-v6-c-drawer__panel--md--FlexBasis--min: 200px;'
|
143
|
+
);
|
144
|
+
});
|
145
|
+
|
146
|
+
it('should accept drawerContentProps', () => {
|
147
|
+
const { container } = render(
|
148
|
+
<ChatbotConversationHistoryNav
|
149
|
+
onDrawerToggle={onDrawerToggle}
|
150
|
+
isDrawerOpen={true}
|
151
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
152
|
+
setIsDrawerOpen={jest.fn()}
|
153
|
+
conversations={initialConversations}
|
154
|
+
drawerContentProps={{ className: 'test' }}
|
155
|
+
/>
|
156
|
+
);
|
157
|
+
const element = container.querySelector('.test');
|
158
|
+
expect(element).toBeInTheDocument();
|
159
|
+
});
|
160
|
+
|
161
|
+
it('should accept drawerContentBodyProps', () => {
|
162
|
+
const { container } = render(
|
163
|
+
<ChatbotConversationHistoryNav
|
164
|
+
onDrawerToggle={onDrawerToggle}
|
165
|
+
isDrawerOpen={true}
|
166
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
167
|
+
setIsDrawerOpen={jest.fn()}
|
168
|
+
conversations={initialConversations}
|
169
|
+
drawerContentBodyProps={{ className: 'test' }}
|
170
|
+
/>
|
171
|
+
);
|
172
|
+
const element = container.querySelector('.test');
|
173
|
+
expect(element).toBeInTheDocument();
|
174
|
+
});
|
175
|
+
|
176
|
+
it('should accept drawerHeadProps', () => {
|
177
|
+
const { container } = render(
|
178
|
+
<ChatbotConversationHistoryNav
|
179
|
+
onDrawerToggle={onDrawerToggle}
|
180
|
+
isDrawerOpen={true}
|
181
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
182
|
+
setIsDrawerOpen={jest.fn()}
|
183
|
+
conversations={initialConversations}
|
184
|
+
drawerHeadProps={{ className: 'test' }}
|
185
|
+
/>
|
186
|
+
);
|
187
|
+
const element = container.querySelector('.test');
|
188
|
+
expect(element).toBeInTheDocument();
|
189
|
+
});
|
190
|
+
|
191
|
+
it('should accept drawerActionsProps', () => {
|
192
|
+
const { container } = render(
|
193
|
+
<ChatbotConversationHistoryNav
|
194
|
+
onDrawerToggle={onDrawerToggle}
|
195
|
+
isDrawerOpen={true}
|
196
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
197
|
+
setIsDrawerOpen={jest.fn()}
|
198
|
+
conversations={initialConversations}
|
199
|
+
drawerActionsProps={{ className: 'test' }}
|
200
|
+
/>
|
201
|
+
);
|
202
|
+
const element = container.querySelector('.test');
|
203
|
+
expect(element).toBeInTheDocument();
|
204
|
+
});
|
205
|
+
|
206
|
+
it('should accept drawerCloseButtonProps', () => {
|
207
|
+
const { container } = render(
|
208
|
+
<ChatbotConversationHistoryNav
|
209
|
+
onDrawerToggle={onDrawerToggle}
|
210
|
+
isDrawerOpen={true}
|
211
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
212
|
+
setIsDrawerOpen={jest.fn()}
|
213
|
+
conversations={initialConversations}
|
214
|
+
drawerCloseButtonProps={{ className: 'test' }}
|
215
|
+
/>
|
216
|
+
);
|
217
|
+
const element = container.querySelector('.test');
|
218
|
+
expect(element).toBeInTheDocument();
|
219
|
+
});
|
220
|
+
|
221
|
+
it('should accept drawerPanelBodyProps', () => {
|
222
|
+
const { container } = render(
|
223
|
+
<ChatbotConversationHistoryNav
|
224
|
+
onDrawerToggle={onDrawerToggle}
|
225
|
+
isDrawerOpen={true}
|
226
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
227
|
+
setIsDrawerOpen={jest.fn()}
|
228
|
+
conversations={initialConversations}
|
229
|
+
drawerPanelBodyProps={{ className: 'test' }}
|
230
|
+
/>
|
231
|
+
);
|
232
|
+
const element = container.querySelector('.test');
|
233
|
+
expect(element).toBeInTheDocument();
|
234
|
+
});
|
126
235
|
});
|
@@ -20,7 +20,16 @@ import {
|
|
20
20
|
MenuList,
|
21
21
|
MenuGroup,
|
22
22
|
MenuItem,
|
23
|
-
MenuContent
|
23
|
+
MenuContent,
|
24
|
+
MenuItemProps,
|
25
|
+
MenuProps,
|
26
|
+
DrawerPanelContentProps,
|
27
|
+
DrawerContentProps,
|
28
|
+
DrawerContentBodyProps,
|
29
|
+
DrawerHeadProps,
|
30
|
+
DrawerActionsProps,
|
31
|
+
DrawerCloseButtonProps,
|
32
|
+
DrawerPanelBodyProps
|
24
33
|
} from '@patternfly/react-core';
|
25
34
|
|
26
35
|
import { OutlinedCommentAltIcon } from '@patternfly/react-icons';
|
@@ -44,6 +53,8 @@ export interface Conversation {
|
|
44
53
|
label?: string;
|
45
54
|
/** Callback for when user selects item. */
|
46
55
|
onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
|
56
|
+
/** Additional props passed to conversation menu item */
|
57
|
+
additionalProps?: MenuItemProps;
|
47
58
|
}
|
48
59
|
export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
49
60
|
/** Function called to toggle drawer */
|
@@ -76,6 +87,22 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
76
87
|
reverseButtonOrder?: boolean;
|
77
88
|
/** Custom test id for the drawer actions */
|
78
89
|
drawerActionsTestId?: string;
|
90
|
+
/** Additional props applied to menu */
|
91
|
+
menuProps?: MenuProps;
|
92
|
+
/** Additional props applied to panel */
|
93
|
+
drawerPanelContentProps?: DrawerPanelContentProps;
|
94
|
+
/** Additional props applied to drawer content */
|
95
|
+
drawerContentProps?: Omit<DrawerContentProps, 'panelContent'>;
|
96
|
+
/** Additional props applied to drawer content body */
|
97
|
+
drawerContentBodyProps?: DrawerContentBodyProps;
|
98
|
+
/** Additional props applied to drawer head */
|
99
|
+
drawerHeadProps?: DrawerHeadProps;
|
100
|
+
/** Additional props applied to drawer actions */
|
101
|
+
drawerActionsProps?: DrawerActionsProps;
|
102
|
+
/** Additional props applied to drawer close button */
|
103
|
+
drawerCloseButtonProps?: DrawerCloseButtonProps;
|
104
|
+
/** Additional props appleid to drawer panel body */
|
105
|
+
drawerPanelBodyProps?: DrawerPanelBodyProps;
|
79
106
|
}
|
80
107
|
|
81
108
|
export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps> = ({
|
@@ -94,6 +121,14 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
94
121
|
displayMode,
|
95
122
|
reverseButtonOrder = false,
|
96
123
|
drawerActionsTestId = 'chatbot-nav-drawer-actions',
|
124
|
+
menuProps,
|
125
|
+
drawerPanelContentProps,
|
126
|
+
drawerContentProps,
|
127
|
+
drawerContentBodyProps,
|
128
|
+
drawerHeadProps,
|
129
|
+
drawerActionsProps,
|
130
|
+
drawerCloseButtonProps,
|
131
|
+
drawerPanelBodyProps,
|
97
132
|
...props
|
98
133
|
}: ChatbotConversationHistoryNavProps) => {
|
99
134
|
const drawerRef = React.useRef<HTMLDivElement>(null);
|
@@ -104,7 +139,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
104
139
|
|
105
140
|
const getNavItem = (conversation: Conversation) => (
|
106
141
|
<MenuItem
|
107
|
-
className=
|
142
|
+
className={`pf-chatbot__menu-item ${activeItemId && activeItemId === conversation.id ? 'pf-chatbot__menu-item--active' : ''}`}
|
108
143
|
itemId={conversation.id}
|
109
144
|
key={conversation.id}
|
110
145
|
{...(conversation.noIcon ? {} : { icon: conversation.icon ?? <OutlinedCommentAltIcon /> })}
|
@@ -121,6 +156,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
121
156
|
)
|
122
157
|
}
|
123
158
|
: {})}
|
159
|
+
{...conversation.additionalProps}
|
124
160
|
/* eslint-enable indent */
|
125
161
|
>
|
126
162
|
{conversation.text}
|
@@ -159,19 +195,20 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
159
195
|
// - Consumers should pass an array to <Chatbot> of the list of conversations
|
160
196
|
// - Groups could be optional, but items need to be ordered by date
|
161
197
|
const menuContent = (
|
162
|
-
<Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId}>
|
198
|
+
<Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
|
163
199
|
<MenuContent>{buildMenu()}</MenuContent>
|
164
200
|
</Menu>
|
165
201
|
);
|
166
202
|
|
167
203
|
const panelContent = (
|
168
|
-
<DrawerPanelContent focusTrap={{ enabled: true }}
|
169
|
-
<DrawerHead>
|
204
|
+
<DrawerPanelContent focusTrap={{ enabled: true }} defaultSize="384px" {...drawerPanelContentProps}>
|
205
|
+
<DrawerHead {...drawerHeadProps}>
|
170
206
|
<DrawerActions
|
171
207
|
data-testid={drawerActionsTestId}
|
172
208
|
className={reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : ''}
|
209
|
+
{...drawerActionsProps}
|
173
210
|
>
|
174
|
-
<DrawerCloseButton onClick={onDrawerToggle} />
|
211
|
+
<DrawerCloseButton onClick={onDrawerToggle} {...drawerCloseButtonProps} />
|
175
212
|
{onNewChat && <Button onClick={onNewChat}>{newChatButtonText}</Button>}
|
176
213
|
</DrawerActions>
|
177
214
|
</DrawerHead>
|
@@ -184,7 +221,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
184
221
|
/>
|
185
222
|
</div>
|
186
223
|
)}
|
187
|
-
<DrawerPanelBody>{menuContent}</DrawerPanelBody>
|
224
|
+
<DrawerPanelBody {...drawerPanelBodyProps}>{menuContent}</DrawerPanelBody>
|
188
225
|
</DrawerPanelContent>
|
189
226
|
);
|
190
227
|
|
@@ -209,8 +246,8 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
|
|
209
246
|
isInline={displayMode === ChatbotDisplayMode.fullscreen || displayMode === ChatbotDisplayMode.embedded}
|
210
247
|
{...props}
|
211
248
|
>
|
212
|
-
<DrawerContent panelContent={panelContent}>
|
213
|
-
<DrawerContentBody>
|
249
|
+
<DrawerContent panelContent={panelContent} {...drawerContentProps}>
|
250
|
+
<DrawerContentBody {...drawerContentBodyProps}>
|
214
251
|
<>
|
215
252
|
<div
|
216
253
|
className={`${isDrawerOpen && (displayMode === ChatbotDisplayMode.default || displayMode === ChatbotDisplayMode.docked) ? 'pf-v6-c-backdrop pf-chatbot__drawer-backdrop' : undefined} `}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
import { Button, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
|
4
|
+
import { CloseIcon } from '@patternfly/react-icons';
|
5
|
+
|
6
|
+
export interface ChatbotHeaderCloseButtonProps {
|
7
|
+
/** Callback function for when button is clicked */
|
8
|
+
onClick: () => void;
|
9
|
+
/** Custom classname for the header component */
|
10
|
+
className?: string;
|
11
|
+
/** Props spread to the PF Tooltip component wrapping the display mode dropdown */
|
12
|
+
tooltipProps?: TooltipProps;
|
13
|
+
/** Aria label for menu */
|
14
|
+
menuAriaLabel?: string;
|
15
|
+
/** Ref applied to menu */
|
16
|
+
innerRef?: React.Ref<HTMLButtonElement>;
|
17
|
+
/** Content used in tooltip */
|
18
|
+
tooltipContent?: string;
|
19
|
+
}
|
20
|
+
|
21
|
+
const ChatbotHeaderCloseButtonBase: React.FunctionComponent<ChatbotHeaderCloseButtonProps> = ({
|
22
|
+
className,
|
23
|
+
onClick,
|
24
|
+
tooltipProps,
|
25
|
+
menuAriaLabel = 'Close',
|
26
|
+
innerRef,
|
27
|
+
tooltipContent = 'Close'
|
28
|
+
}: ChatbotHeaderCloseButtonProps) => (
|
29
|
+
<div className={`pf-chatbot__menu ${className}`}>
|
30
|
+
<Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
|
31
|
+
<Button
|
32
|
+
className="pf-chatbot__button--toggle-menu"
|
33
|
+
variant="plain"
|
34
|
+
onClick={onClick}
|
35
|
+
aria-label={menuAriaLabel}
|
36
|
+
ref={innerRef}
|
37
|
+
icon={
|
38
|
+
<Icon size="xl" isInline>
|
39
|
+
<CloseIcon />
|
40
|
+
</Icon>
|
41
|
+
}
|
42
|
+
/>
|
43
|
+
</Tooltip>
|
44
|
+
</div>
|
45
|
+
);
|
46
|
+
|
47
|
+
export const ChatbotHeaderCloseButton = React.forwardRef(
|
48
|
+
(props: ChatbotHeaderCloseButtonProps, ref: React.Ref<HTMLButtonElement>) => (
|
49
|
+
<ChatbotHeaderCloseButtonBase innerRef={ref} {...props} />
|
50
|
+
)
|
51
|
+
);
|
@@ -14,6 +14,8 @@ export interface ChatbotHeaderMenuProps {
|
|
14
14
|
menuAriaLabel?: string;
|
15
15
|
/** Ref applied to menu */
|
16
16
|
innerRef?: React.Ref<HTMLButtonElement>;
|
17
|
+
/** Content used in tooltip */
|
18
|
+
tooltipContent?: string;
|
17
19
|
}
|
18
20
|
|
19
21
|
const ChatbotHeaderMenuBase: React.FunctionComponent<ChatbotHeaderMenuProps> = ({
|
@@ -21,10 +23,11 @@ const ChatbotHeaderMenuBase: React.FunctionComponent<ChatbotHeaderMenuProps> = (
|
|
21
23
|
onMenuToggle,
|
22
24
|
tooltipProps,
|
23
25
|
menuAriaLabel = 'Toggle menu',
|
24
|
-
innerRef
|
26
|
+
innerRef,
|
27
|
+
tooltipContent = 'Menu'
|
25
28
|
}: ChatbotHeaderMenuProps) => (
|
26
29
|
<div className={`pf-chatbot__menu ${className}`}>
|
27
|
-
<Tooltip content=
|
30
|
+
<Tooltip content={tooltipContent} position="bottom" {...tooltipProps}>
|
28
31
|
<Button
|
29
32
|
className="pf-chatbot__button--toggle-menu"
|
30
33
|
variant="plain"
|
@@ -87,17 +87,6 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
|
|
87
87
|
}
|
88
88
|
};
|
89
89
|
|
90
|
-
/* eslint-disable indent */
|
91
|
-
const getHeight = (displayMode: ChatbotDisplayMode) => {
|
92
|
-
switch (displayMode) {
|
93
|
-
case ChatbotDisplayMode.docked:
|
94
|
-
return '100vh';
|
95
|
-
default:
|
96
|
-
return '45vh';
|
97
|
-
}
|
98
|
-
};
|
99
|
-
/* eslint-enable indent */
|
100
|
-
|
101
90
|
const modal = (
|
102
91
|
<ChatbotModal
|
103
92
|
isOpen={isModalOpen}
|
@@ -114,7 +103,7 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
|
|
114
103
|
<StackItem className="pf-chatbot__code-modal-file-details">
|
115
104
|
<FileDetails fileName={fileName} />
|
116
105
|
</StackItem>
|
117
|
-
<StackItem>
|
106
|
+
<StackItem className="pf-chatbot__code-modal-body">
|
118
107
|
<CodeEditor
|
119
108
|
isDarkTheme
|
120
109
|
isLineNumbersVisible={isLineNumbersVisible}
|
@@ -126,7 +115,7 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
|
|
126
115
|
onEditorDidMount={onEditorDidMount}
|
127
116
|
onCodeChange={onCodeChange}
|
128
117
|
className={codeEditorClassName}
|
129
|
-
|
118
|
+
isFullHeight
|
130
119
|
options={{
|
131
120
|
glyphMargin: false,
|
132
121
|
folding: false
|