@patternfly/chatbot 6.3.1 → 6.4.0-prerelease.10
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/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +6 -6
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +27 -4
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +8 -14
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +53 -2
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- 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/Message.d.ts +9 -2
- package/dist/cjs/Message/Message.js +40 -34
- package/dist/cjs/Message/Message.test.js +37 -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/MessageBar/MessageBar.js +19 -4
- package/dist/cjs/MessageBox/JumpButton.d.ts +5 -0
- package/dist/cjs/MessageBox/JumpButton.js +1 -1
- package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
- package/dist/cjs/MessageBox/MessageBox.d.ts +9 -0
- package/dist/cjs/MessageBox/MessageBox.js +2 -2
- package/dist/cjs/MessageBox/MessageBox.test.js +2 -2
- 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 +103 -81
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/MessageDivider/package.json +1 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +6 -6
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +27 -4
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +10 -16
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +54 -3
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- 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/Message.d.ts +9 -2
- package/dist/esm/Message/Message.js +40 -34
- package/dist/esm/Message/Message.test.js +37 -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/MessageBar/MessageBar.js +19 -4
- package/dist/esm/MessageBox/JumpButton.d.ts +5 -0
- package/dist/esm/MessageBox/JumpButton.js +1 -1
- package/dist/esm/MessageBox/JumpButton.test.js +4 -4
- package/dist/esm/MessageBox/MessageBox.d.ts +9 -0
- package/dist/esm/MessageBox/MessageBox.js +2 -2
- package/dist/esm/MessageBox/MessageBox.test.js +2 -2
- 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 +9 -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/ChatbotConversationEditing.tsx +202 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +17 -3
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +45 -5
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx +206 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +30 -4
- 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/ChatbotConversationHistoryDropdown.test.tsx +6 -6
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +5 -2
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +70 -32
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +176 -3
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +110 -60
- package/src/ChatbotFooter/ChatbotFooter.scss +1 -1
- package/src/ChatbotHeader/ChatbotHeader.scss +3 -3
- package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +1 -1
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +2 -2
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx +25 -0
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx +64 -0
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/ChatbotModal/ChatbotModal.scss +1 -1
- 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/Message.scss +9 -7
- package/src/Message/Message.test.tsx +54 -0
- package/src/Message/Message.tsx +70 -50
- package/src/Message/MessageInput.tsx +5 -1
- package/src/MessageBar/AttachButton.tsx +2 -2
- package/src/MessageBar/MessageBar.tsx +25 -5
- package/src/MessageBar/SendButton.scss +3 -3
- package/src/MessageBox/JumpButton.scss +1 -1
- package/src/MessageBox/JumpButton.test.tsx +4 -4
- package/src/MessageBox/JumpButton.tsx +20 -4
- package/src/MessageBox/MessageBox.test.tsx +2 -2
- package/src/MessageBox/MessageBox.tsx +23 -2
- 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
|
@@ -9,6 +9,8 @@ export interface ChatbotConversationHistoryDropdownProps extends Omit<DropdownPr
|
|
|
9
9
|
label?: string;
|
|
10
10
|
/** Callback for when user selects item. */
|
|
11
11
|
onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
|
|
12
|
+
/** Id applied to dropdown menu toggle */
|
|
13
|
+
id?: string;
|
|
12
14
|
}
|
|
13
15
|
export declare const ChatbotConversationHistoryDropdown: FunctionComponent<ChatbotConversationHistoryDropdownProps>;
|
|
14
16
|
export default ChatbotConversationHistoryDropdown;
|
|
@@ -9,11 +9,11 @@ const react_1 = require("react");
|
|
|
9
9
|
// Import PatternFly components
|
|
10
10
|
const react_core_1 = require("@patternfly/react-core");
|
|
11
11
|
const ellipsis_v_icon_1 = __importDefault(require("@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon"));
|
|
12
|
-
const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label }) => {
|
|
12
|
+
const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label, id }) => {
|
|
13
13
|
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
14
14
|
const toggle = (toggleRef) => ((0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { className: "pf-chatbot__tooltip", content: label !== null && label !== void 0 ? label : 'Conversation options', position: "bottom",
|
|
15
15
|
// prevents VO announcements of both aria label and tooltip
|
|
16
|
-
aria: "none", children: (0, jsx_runtime_1.jsx)(react_core_1.MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": label !== null && label !== void 0 ? label : 'Conversation options', ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen),
|
|
16
|
+
aria: "none", children: (0, jsx_runtime_1.jsx)(react_core_1.MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": label !== null && label !== void 0 ? label : 'Conversation options', ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen), id: id, children: (0, jsx_runtime_1.jsx)(ellipsis_v_icon_1.default, {}) }) }));
|
|
17
17
|
return ((0, jsx_runtime_1.jsx)(react_core_1.Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: (props) => {
|
|
18
18
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(props);
|
|
19
19
|
setIsOpen((prev) => !prev);
|
|
@@ -22,11 +22,11 @@ describe('ChatbotConversationHistoryDropdown', () => {
|
|
|
22
22
|
const menuItems = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DropdownItem, { children: "Rename" }), (0, jsx_runtime_1.jsx)(react_core_1.DropdownItem, { children: "Delete" })] }));
|
|
23
23
|
it('should render the dropdown', () => {
|
|
24
24
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, menuClassName: "custom-class" }));
|
|
25
|
-
expect(react_1.screen.queryByRole('
|
|
25
|
+
expect(react_1.screen.queryByRole('button', { name: /Conversation options/i })).toBeInTheDocument();
|
|
26
26
|
});
|
|
27
27
|
it('should display the dropdown menuItems', () => {
|
|
28
28
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems }));
|
|
29
|
-
const toggle = react_1.screen.queryByRole('
|
|
29
|
+
const toggle = react_1.screen.queryByRole('button', { name: /Conversation options/i });
|
|
30
30
|
expect(toggle).toBeInTheDocument();
|
|
31
31
|
react_1.fireEvent.click(toggle);
|
|
32
32
|
(0, react_1.waitFor)(() => {
|
|
@@ -36,14 +36,14 @@ describe('ChatbotConversationHistoryDropdown', () => {
|
|
|
36
36
|
});
|
|
37
37
|
it('should invoke onSelect callback when menuitem is clicked', () => {
|
|
38
38
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
|
|
39
|
-
const toggle = react_1.screen.queryByRole('
|
|
39
|
+
const toggle = react_1.screen.queryByRole('button', { name: /Conversation options/i });
|
|
40
40
|
react_1.fireEvent.click(toggle);
|
|
41
41
|
react_1.fireEvent.click(react_1.screen.getByText('Rename'));
|
|
42
42
|
expect(onSelect).toHaveBeenCalled();
|
|
43
43
|
});
|
|
44
44
|
it('should toggle the dropdown when menuitem is clicked', () => {
|
|
45
45
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
|
|
46
|
-
const toggle = react_1.screen.queryByRole('
|
|
46
|
+
const toggle = react_1.screen.queryByRole('button', { name: /Conversation options/i });
|
|
47
47
|
react_1.fireEvent.click(toggle);
|
|
48
48
|
react_1.fireEvent.click(react_1.screen.getByText('Delete'));
|
|
49
49
|
expect(onSelect).toHaveBeenCalled();
|
|
@@ -51,7 +51,7 @@ describe('ChatbotConversationHistoryDropdown', () => {
|
|
|
51
51
|
});
|
|
52
52
|
it('should close the dropdown when user clicks outside', () => {
|
|
53
53
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
|
|
54
|
-
const toggle = react_1.screen.queryByRole('
|
|
54
|
+
const toggle = react_1.screen.queryByRole('button', { name: /Conversation options/i });
|
|
55
55
|
react_1.fireEvent.click(toggle);
|
|
56
56
|
expect(react_1.screen.queryByText('Delete')).toBeInTheDocument();
|
|
57
57
|
react_1.fireEvent.click(toggle.parentElement);
|
|
@@ -59,7 +59,7 @@ describe('ChatbotConversationHistoryDropdown', () => {
|
|
|
59
59
|
});
|
|
60
60
|
it('should show the tooltip when the user hovers over the toggle button', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
61
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, label: "Actions dropdown" }));
|
|
62
|
-
const toggle = react_1.screen.queryByRole('
|
|
62
|
+
const toggle = react_1.screen.queryByRole('button', { name: /Actions dropdown/i });
|
|
63
63
|
(0, react_1.fireEvent)(toggle, new MouseEvent('mouseenter', {
|
|
64
64
|
bubbles: false,
|
|
65
65
|
cancelable: false
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ButtonProps, DrawerProps, ListItemProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps, MenuProps, // Remove in next breaking change
|
|
3
|
+
TitleProps, ListProps, SearchInputProps } from '@patternfly/react-core';
|
|
3
4
|
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
|
|
4
5
|
import { HistoryEmptyStateProps } from './EmptyState';
|
|
5
6
|
export interface Conversation {
|
|
@@ -19,8 +20,12 @@ export interface Conversation {
|
|
|
19
20
|
label?: string;
|
|
20
21
|
/** Callback for when user selects item. */
|
|
21
22
|
onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
|
|
22
|
-
/** Additional props passed to conversation
|
|
23
|
-
additionalProps?:
|
|
23
|
+
/** Additional props passed to conversation button item */
|
|
24
|
+
additionalProps?: ButtonProps;
|
|
25
|
+
/** Additional props passed to conversation list item */
|
|
26
|
+
listItemProps?: Omit<ListItemProps, 'children'>;
|
|
27
|
+
/** Custom dropdown ID to ensure uniqueness across demo instances */
|
|
28
|
+
dropdownId?: string;
|
|
24
29
|
}
|
|
25
30
|
export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
26
31
|
/** Function called to toggle drawer */
|
|
@@ -36,6 +41,14 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
36
41
|
conversations: Conversation[] | {
|
|
37
42
|
[key: string]: Conversation[];
|
|
38
43
|
};
|
|
44
|
+
/** Additional button props for new chat button. */
|
|
45
|
+
newChatButtonProps?: ButtonProps;
|
|
46
|
+
/** Additional props applied to all conversation list headers */
|
|
47
|
+
listTitleProps?: Partial<TitleProps>;
|
|
48
|
+
/** Additional props applied to conversation list. If conversations is an object, you should pass an object of ListProps for each group. */
|
|
49
|
+
listProps?: ListProps | {
|
|
50
|
+
[key: string]: ListProps;
|
|
51
|
+
};
|
|
39
52
|
/** Text shown in blue button */
|
|
40
53
|
newChatButtonText?: string;
|
|
41
54
|
/** Callback function for when blue button is clicked. Omit to hide blue "new chat button" */
|
|
@@ -46,6 +59,8 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
46
59
|
searchInputPlaceholder?: string;
|
|
47
60
|
/** Aria label for search input */
|
|
48
61
|
searchInputAriaLabel?: string;
|
|
62
|
+
/** Additional props passed to search input */
|
|
63
|
+
searchInputProps?: SearchInputProps;
|
|
49
64
|
/** A callback for when the input value changes. Omit to hide input field */
|
|
50
65
|
handleTextInputChange?: (value: string) => void;
|
|
51
66
|
/** Display mode of chatbot */
|
|
@@ -54,7 +69,7 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
54
69
|
reverseButtonOrder?: boolean;
|
|
55
70
|
/** Custom test id for the drawer actions */
|
|
56
71
|
drawerActionsTestId?: string;
|
|
57
|
-
/** Additional props applied to
|
|
72
|
+
/** @deprecated Additional props applied to list container */
|
|
58
73
|
menuProps?: MenuProps;
|
|
59
74
|
/** Additional props applied to panel */
|
|
60
75
|
drawerPanelContentProps?: DrawerPanelContentProps;
|
|
@@ -82,6 +97,14 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
82
97
|
noResultsState?: HistoryEmptyStateProps;
|
|
83
98
|
/** Sets drawer to compact styling. */
|
|
84
99
|
isCompact?: boolean;
|
|
100
|
+
/** Display title */
|
|
101
|
+
title?: string;
|
|
102
|
+
/** Icon displayed in title */
|
|
103
|
+
navTitleIcon?: React.ReactNode;
|
|
104
|
+
/** Title header level */
|
|
105
|
+
navTitleProps?: Partial<TitleProps>;
|
|
106
|
+
/** Visually hidden text that gets announced by assistive technologies. Should be used to convey the result count when the search input value changes. */
|
|
107
|
+
searchInputScreenReaderText?: string;
|
|
85
108
|
}
|
|
86
109
|
export declare const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversationHistoryNavProps>;
|
|
87
110
|
export default ChatbotConversationHistoryNav;
|
|
@@ -25,27 +25,21 @@ const ChatbotConversationHistoryDropdown_1 = __importDefault(require("./ChatbotC
|
|
|
25
25
|
const LoadingState_1 = __importDefault(require("./LoadingState"));
|
|
26
26
|
const EmptyState_1 = __importDefault(require("./EmptyState"));
|
|
27
27
|
const ChatbotConversationHistoryNav = (_a) => {
|
|
28
|
-
var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, newChatButtonText = 'New chat', drawerContent, onNewChat, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = '
|
|
28
|
+
var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, listTitleProps, listProps, newChatButtonText = 'New chat', drawerContent, onNewChat, newChatButtonProps, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = 'Search previous conversations', searchInputProps, handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, isLoading, loadingState, errorState, emptyState, noResultsState, isCompact, title = 'Chat history', navTitleProps, navTitleIcon = (0, jsx_runtime_1.jsx)(react_icons_1.OutlinedClockIcon, {}), searchInputScreenReaderText } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "listTitleProps", "listProps", "newChatButtonText", "drawerContent", "onNewChat", "newChatButtonProps", "searchInputPlaceholder", "searchInputAriaLabel", "searchInputProps", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "isLoading", "loadingState", "errorState", "emptyState", "noResultsState", "isCompact", "title", "navTitleProps", "navTitleIcon", "searchInputScreenReaderText"]);
|
|
29
29
|
const drawerRef = (0, react_1.useRef)(null);
|
|
30
30
|
const onExpand = () => {
|
|
31
31
|
drawerRef.current && drawerRef.current.focus();
|
|
32
32
|
};
|
|
33
33
|
const getNavItem = (conversation) => {
|
|
34
34
|
var _a;
|
|
35
|
-
return ((0, jsx_runtime_1.jsx)(react_core_1.
|
|
36
|
-
? {
|
|
37
|
-
actions: ((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuClassName: conversation.menuClassName, onSelect: conversation.onSelect, menuItems: conversation.menuItems, label: conversation.label }))
|
|
38
|
-
}
|
|
39
|
-
: {}), conversation.additionalProps, { children: conversation.text }), conversation.id));
|
|
35
|
+
return ((0, jsx_runtime_1.jsx)(react_core_1.ListItem, Object.assign({ className: `pf-chatbot__conversation-list-item ${activeItemId && activeItemId === conversation.id ? 'pf-chatbot__conversation-list-item--active' : ''}` }, conversation.listItemProps, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: "pf-chatbot__conversation-history-item", variant: "link" }, conversation.additionalProps, (conversation.noIcon ? {} : { icon: (_a = conversation.icon) !== null && _a !== void 0 ? _a : (0, jsx_runtime_1.jsx)(react_icons_1.OutlinedCommentAltIcon, {}) }), { onClick: (event) => onSelectActiveItem === null || onSelectActiveItem === void 0 ? void 0 : onSelectActiveItem(event, conversation.id), children: conversation.text })), conversation.menuItems && ((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuClassName: conversation.menuClassName, onSelect: conversation.onSelect, menuItems: conversation.menuItems, label: conversation.label, id: conversation.dropdownId }))] }) }), conversation.id));
|
|
40
36
|
};
|
|
41
|
-
const
|
|
37
|
+
const buildConversations = () => {
|
|
42
38
|
if (Array.isArray(conversations)) {
|
|
43
|
-
|
|
44
|
-
return ((0, jsx_runtime_1.jsx)(react_core_1.MenuList, { children: conversations.map((conversation) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: getNavItem(conversation) }, conversation.id))) }));
|
|
39
|
+
return ((0, jsx_runtime_1.jsx)(react_core_1.List, Object.assign({ className: "pf-chatbot__conversation-list", isPlain: true }, listProps, { children: conversations.map((conversation) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: getNavItem(conversation) }, conversation.id))) })));
|
|
45
40
|
}
|
|
46
41
|
else {
|
|
47
|
-
|
|
48
|
-
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Object.keys(conversations).map((navGroup) => ((0, jsx_runtime_1.jsx)(react_core_1.MenuGroup, { className: "pf-chatbot__menu-item-header", label: navGroup, children: (0, jsx_runtime_1.jsx)(react_core_1.MenuList, { children: conversations[navGroup].map((conversation) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: getNavItem(conversation) }, conversation.id))) }) }, navGroup))) }));
|
|
42
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: Object.keys(conversations).map((navGroup) => ((0, jsx_runtime_1.jsxs)("section", { children: [(0, jsx_runtime_1.jsx)(react_core_1.Title, Object.assign({ headingLevel: "h4", className: "pf-chatbot__conversation-list-header" }, listTitleProps, { children: navGroup })), (0, jsx_runtime_1.jsx)(react_core_1.List, Object.assign({ className: "pf-chatbot__conversation-list", isPlain: true }, listProps === null || listProps === void 0 ? void 0 : listProps[navGroup], { children: conversations[navGroup].map((conversation) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: getNavItem(conversation) }, conversation.id))) }))] }, navGroup))) }));
|
|
49
43
|
}
|
|
50
44
|
};
|
|
51
45
|
// Menu Content
|
|
@@ -61,11 +55,11 @@ const ChatbotConversationHistoryNav = (_a) => {
|
|
|
61
55
|
if (noResultsState) {
|
|
62
56
|
return (0, jsx_runtime_1.jsx)(EmptyState_1.default, Object.assign({}, noResultsState));
|
|
63
57
|
}
|
|
64
|
-
return (
|
|
58
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: buildConversations() });
|
|
65
59
|
};
|
|
66
|
-
const renderDrawerContent = () => ((0, jsx_runtime_1.
|
|
60
|
+
const renderDrawerContent = () => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_core_1.DrawerPanelBody, Object.assign({}, drawerPanelBodyProps, { children: renderMenuContent() })) }));
|
|
67
61
|
const renderPanelContent = () => {
|
|
68
|
-
const drawer = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && ((0, jsx_runtime_1.jsx)(react_core_1.Button, { size: isCompact ? 'sm' : undefined, onClick: onNewChat, children: newChatButtonText }))] })) })), isLoading ? (0, jsx_runtime_1.jsx)(LoadingState_1.default, Object.assign({}, loadingState)) : renderDrawerContent()] }));
|
|
62
|
+
const drawer = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ size: isCompact ? 'sm' : undefined, onClick: onNewChat, icon: (0, jsx_runtime_1.jsx)(react_icons_1.PenToSquareIcon, {}) }, newChatButtonProps, { children: newChatButtonText })))] })) })), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__heading-container", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__title-container", children: [(0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: "lg", className: "pf-chatbot__title-icon", children: navTitleIcon }), (0, jsx_runtime_1.jsx)(react_core_1.Title, Object.assign({ className: "pf-chatbot__title", headingLevel: "h2" }, navTitleProps, { children: title }))] }), !isLoading && handleTextInputChange && ((0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__input", children: [(0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)), searchInputScreenReaderText && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__filter-announcement", children: searchInputScreenReaderText }))] }))] }), isLoading ? (0, jsx_runtime_1.jsx)(LoadingState_1.default, Object.assign({}, loadingState)) : renderDrawerContent()] }));
|
|
69
63
|
return ((0, jsx_runtime_1.jsx)(react_core_1.DrawerPanelContent, Object.assign({ "aria-live": "polite", focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps, { children: drawer })));
|
|
70
64
|
};
|
|
71
65
|
// An onKeyDown property must be passed to the Drawer component to handle closing
|
|
@@ -70,6 +70,10 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
70
70
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: true, conversations: initialConversations }));
|
|
71
71
|
expect(react_1.screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
|
|
72
72
|
});
|
|
73
|
+
it('should disable new chat button', () => {
|
|
74
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: true, conversations: initialConversations, newChatButtonProps: { isDisabled: true }, onNewChat: jest.fn() }));
|
|
75
|
+
expect(react_1.screen.getByRole('button', { name: 'New chat' })).toBeDisabled();
|
|
76
|
+
});
|
|
73
77
|
it('should not apply the reversed class when reverseButtonOrder is false', () => {
|
|
74
78
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: initialConversations }));
|
|
75
79
|
expect(react_1.screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
|
|
@@ -148,7 +152,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
148
152
|
})).toBeTruthy();
|
|
149
153
|
expect(react_1.screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
|
|
150
154
|
expect(react_1.screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
|
|
151
|
-
expect(react_1.screen.getByRole('textbox', { name: /
|
|
155
|
+
expect(react_1.screen.getByRole('textbox', { name: /Search previous conversations/i })).toBeTruthy();
|
|
152
156
|
expect(react_1.screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
|
|
153
157
|
});
|
|
154
158
|
it('should accept errorState without button', () => {
|
|
@@ -158,7 +162,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
158
162
|
})).toBeTruthy();
|
|
159
163
|
expect(react_1.screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
|
|
160
164
|
expect(react_1.screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
|
|
161
|
-
expect(react_1.screen.getByRole('textbox', { name: /
|
|
165
|
+
expect(react_1.screen.getByRole('textbox', { name: /Search previous conversations/i })).toBeTruthy();
|
|
162
166
|
expect(react_1.screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
|
|
163
167
|
});
|
|
164
168
|
it('should show loading state over error state if both are supplied', () => {
|
|
@@ -181,4 +185,51 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
181
185
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, noResultsState: NO_RESULTS, isCompact: true, "data-testid": "drawer" }));
|
|
182
186
|
expect(react_1.screen.getByTestId('drawer')).toHaveClass('pf-m-compact');
|
|
183
187
|
});
|
|
188
|
+
it('should display the default title', () => {
|
|
189
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations }));
|
|
190
|
+
expect(react_1.screen.getByText('Chat history')).toBeInTheDocument();
|
|
191
|
+
});
|
|
192
|
+
it('should display the custom title', () => {
|
|
193
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { title: "PatternFly history", onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations }));
|
|
194
|
+
expect(react_1.screen.getByText('PatternFly history')).toBeInTheDocument();
|
|
195
|
+
});
|
|
196
|
+
it('should display the clock icon', () => {
|
|
197
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations }));
|
|
198
|
+
const iconElement = container.querySelector('.pf-chatbot__title-icon');
|
|
199
|
+
expect(iconElement).toBeInTheDocument();
|
|
200
|
+
});
|
|
201
|
+
it('Passes listTitleProps to Title', () => {
|
|
202
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, listTitleProps: { className: 'test' } }));
|
|
203
|
+
expect(react_1.screen.getByRole('heading', { name: /Today/i })).toHaveClass('test');
|
|
204
|
+
});
|
|
205
|
+
it('Overrides list title heading level when titleProps.headingLevel is passed', () => {
|
|
206
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, listTitleProps: { headingLevel: 'h2' } }));
|
|
207
|
+
expect(react_1.screen.queryByRole('heading', { name: /Today/i, level: 4 })).not.toBeInTheDocument();
|
|
208
|
+
expect(react_1.screen.getByRole('heading', { name: /Today/i, level: 2 })).toBeInTheDocument();
|
|
209
|
+
});
|
|
210
|
+
it('Passes listProps to List when conversations is an array', () => {
|
|
211
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations, listProps: { className: 'test' } }));
|
|
212
|
+
expect(react_1.screen.getByRole('list')).toHaveClass('test');
|
|
213
|
+
});
|
|
214
|
+
it('Passes listProps to List when conversations is an object', () => {
|
|
215
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, listProps: { Today: { className: 'test' } } }));
|
|
216
|
+
expect(react_1.screen.getByRole('list')).toHaveClass('test');
|
|
217
|
+
});
|
|
218
|
+
it('Passes listItemProps to ListItem', () => {
|
|
219
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: [{ id: '1', text: 'ChatBot documentation', listItemProps: { className: 'test' } }] }));
|
|
220
|
+
expect(react_1.screen.getByRole('listitem')).toHaveClass('test');
|
|
221
|
+
});
|
|
222
|
+
it('should be able to spread search input props when searchInputProps is passed', () => {
|
|
223
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations, handleTextInputChange: jest.fn(), searchInputProps: { value: 'I am a sample search' } }));
|
|
224
|
+
expect(react_1.screen.getByRole('dialog', { name: /Chat history I am a sample search/i })).toBeInTheDocument();
|
|
225
|
+
});
|
|
226
|
+
it('overrides nav title heading level when navTitleProps.headingLevel is passed', () => {
|
|
227
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, navTitleProps: { headingLevel: 'h1' } }));
|
|
228
|
+
expect(react_1.screen.queryByRole('heading', { name: /Chat history/i, level: 2 })).not.toBeInTheDocument();
|
|
229
|
+
expect(react_1.screen.getByRole('heading', { name: /Chat history/i, level: 1 })).toBeInTheDocument();
|
|
230
|
+
});
|
|
231
|
+
it('overrides nav title icon when navTitleIcon is passed in', () => {
|
|
232
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations, navTitleIcon: (0, jsx_runtime_1.jsx)(react_icons_1.BellIcon, { "data-testid": "bell" }) }));
|
|
233
|
+
expect(react_1.screen.getByTestId('bell')).toBeInTheDocument();
|
|
234
|
+
});
|
|
184
235
|
});
|
|
@@ -20,7 +20,7 @@ const react_1 = require("react");
|
|
|
20
20
|
const react_core_1 = require("@patternfly/react-core");
|
|
21
21
|
const bars_icon_1 = __importDefault(require("@patternfly/react-icons/dist/esm/icons/bars-icon"));
|
|
22
22
|
const ChatbotHeaderMenuBase = (_a) => {
|
|
23
|
-
var { className, onMenuToggle, tooltipProps, menuAriaLabel = '
|
|
23
|
+
var { className, onMenuToggle, tooltipProps, menuAriaLabel = 'Chat history menu', innerRef, tooltipContent = 'Chat history menu', isCompact } = _a, props = __rest(_a, ["className", "onMenuToggle", "tooltipProps", "menuAriaLabel", "innerRef", "tooltipContent", "isCompact"]);
|
|
24
24
|
return ((0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__menu ${className}`, children: (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
|
|
25
25
|
// prevents VO announcements of both aria label and tooltip
|
|
26
26
|
aria: "none" }, tooltipProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onMenuToggle, "aria-label": menuAriaLabel, ref: innerRef, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: (0, jsx_runtime_1.jsx)(bars_icon_1.default, {}) }), size: isCompact ? 'sm' : undefined }, props)) })) }));
|
|
@@ -12,7 +12,7 @@ describe('ChatbotHeaderMenu', () => {
|
|
|
12
12
|
it('should call onMenuToggle when ChatbotHeaderMenu button is clicked', () => {
|
|
13
13
|
const onMenuToggle = jest.fn();
|
|
14
14
|
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotHeaderMenu_1.ChatbotHeaderMenu, { className: "custom-header-menu", onMenuToggle: onMenuToggle }));
|
|
15
|
-
react_1.fireEvent.click(react_1.screen.getByRole('button', { name: '
|
|
15
|
+
react_1.fireEvent.click(react_1.screen.getByRole('button', { name: 'Chat history menu' }));
|
|
16
16
|
expect(onMenuToggle).toHaveBeenCalled();
|
|
17
17
|
});
|
|
18
18
|
it('should handle isCompact', () => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
|
2
|
+
export interface ChatbotHeaderNewChatButtonProps extends ButtonProps {
|
|
3
|
+
/** Callback function for when button is clicked */
|
|
4
|
+
onClick: () => void;
|
|
5
|
+
/** Custom classname for the header component */
|
|
6
|
+
className?: string;
|
|
7
|
+
/** Props spread to the PF Tooltip component wrapping the display mode dropdown */
|
|
8
|
+
tooltipProps?: TooltipProps;
|
|
9
|
+
/** Aria label for menu */
|
|
10
|
+
menuAriaLabel?: string;
|
|
11
|
+
/** Ref applied to menu */
|
|
12
|
+
innerRef?: React.Ref<HTMLButtonElement>;
|
|
13
|
+
/** Content used in tooltip */
|
|
14
|
+
tooltipContent?: string;
|
|
15
|
+
/** Sets button to compact styling. */
|
|
16
|
+
isCompact?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const ChatbotHeaderNewChatButton: import("react").ForwardRefExoticComponent<ChatbotHeaderNewChatButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.ChatbotHeaderNewChatButton = void 0;
|
|
15
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
+
const react_1 = require("react");
|
|
17
|
+
const react_core_1 = require("@patternfly/react-core");
|
|
18
|
+
const pen_to_square_icon_1 = require("@patternfly/react-icons/dist/esm/icons/pen-to-square-icon");
|
|
19
|
+
const ChatbotHeaderNewChatButtonBase = (_a) => {
|
|
20
|
+
var { className, onClick, tooltipProps, menuAriaLabel = 'New chat', innerRef, tooltipContent = 'New chat', isCompact } = _a, props = __rest(_a, ["className", "onClick", "tooltipProps", "menuAriaLabel", "innerRef", "tooltipContent", "isCompact"]);
|
|
21
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__menu${className ? ` ${className}` : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
|
|
22
|
+
// prevents VO announcements of both aria label and tooltip
|
|
23
|
+
aria: "none" }, tooltipProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onClick, "aria-label": menuAriaLabel, ref: innerRef, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: (0, jsx_runtime_1.jsx)(pen_to_square_icon_1.PenToSquareIcon, {}) }), size: isCompact ? 'sm' : undefined }, props)) })) }));
|
|
24
|
+
};
|
|
25
|
+
exports.ChatbotHeaderNewChatButton = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(ChatbotHeaderNewChatButtonBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
|
+
const react_1 = require("@testing-library/react");
|
|
5
|
+
const ChatbotHeaderNewChatButton_1 = require("./ChatbotHeaderNewChatButton");
|
|
6
|
+
require("@testing-library/jest-dom");
|
|
7
|
+
describe('ChatbotHeaderNewChatButton', () => {
|
|
8
|
+
it('should render ChatbotHeaderNewChatButton', () => {
|
|
9
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotHeaderNewChatButton_1.ChatbotHeaderNewChatButton, { className: "custom-header-new-chat-button", onClick: jest.fn() }));
|
|
10
|
+
expect(container.querySelector('.custom-header-new-chat-button')).toBeTruthy();
|
|
11
|
+
});
|
|
12
|
+
it('should call onClick handler when new chat button is pressed', () => {
|
|
13
|
+
const onClick = jest.fn();
|
|
14
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotHeaderNewChatButton_1.ChatbotHeaderNewChatButton, { className: "custom-header-new-chat-button", onClick: onClick }));
|
|
15
|
+
react_1.fireEvent.click(react_1.screen.getByRole('button', { name: 'New chat' }));
|
|
16
|
+
expect(onClick).toHaveBeenCalled();
|
|
17
|
+
});
|
|
18
|
+
it('should render button with isCompact', () => {
|
|
19
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotHeaderNewChatButton_1.ChatbotHeaderNewChatButton, { "data-testid": "new-chat-button", onClick: jest.fn(), isCompact: true }));
|
|
20
|
+
expect(react_1.screen.getByTestId('new-chat-button')).toHaveClass('pf-m-compact');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -28,3 +28,4 @@ __exportStar(require("./ChatbotHeaderTitle"), exports);
|
|
|
28
28
|
__exportStar(require("./ChatbotHeaderOptionsDropdown"), exports);
|
|
29
29
|
__exportStar(require("./ChatbotHeaderSelectorDropdown"), exports);
|
|
30
30
|
__exportStar(require("./ChatbotHeaderCloseButton"), exports);
|
|
31
|
+
__exportStar(require("./ChatbotHeaderNewChatButton"), exports);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { DropEvent } from '@patternfly/react-core';
|
|
2
1
|
import type { FunctionComponent } from 'react';
|
|
3
2
|
import { ChatbotDisplayMode } from '../Chatbot';
|
|
4
|
-
import { Accept, FileError, FileRejection } from 'react-dropzone
|
|
3
|
+
import { Accept, DropEvent, FileError, FileRejection } from 'react-dropzone';
|
|
5
4
|
export interface FileDropZoneProps {
|
|
6
5
|
/** Content displayed when the drop zone is not currently in use */
|
|
7
6
|
children?: React.ReactNode;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import type { FunctionComponent, HTMLProps, MouseEvent as ReactMouseEvent, Ref } from 'react';
|
|
3
|
+
import { Options } from 'react-markdown';
|
|
3
4
|
import { AlertProps, AvatarProps, ButtonProps, ExpandableSectionProps, ExpandableSectionToggleProps, FormProps, LabelGroupProps } from '@patternfly/react-core';
|
|
4
5
|
import { ActionProps } from '../ResponseActions/ResponseActions';
|
|
5
6
|
import { SourcesCardProps } from '../SourcesCard';
|
|
@@ -8,7 +9,7 @@ import QuickResponse from './QuickResponse/QuickResponse';
|
|
|
8
9
|
import { UserFeedbackProps } from './UserFeedback/UserFeedback';
|
|
9
10
|
import { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete';
|
|
10
11
|
import { TableProps } from '@patternfly/react-table';
|
|
11
|
-
import { PluggableList } from '
|
|
12
|
+
import { PluggableList } from 'unified';
|
|
12
13
|
export interface MessageAttachment {
|
|
13
14
|
/** Name of file attached to the message */
|
|
14
15
|
name: string;
|
|
@@ -54,7 +55,7 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
54
55
|
isLoading?: boolean;
|
|
55
56
|
/** Array of attachments attached to a message */
|
|
56
57
|
attachments?: MessageAttachment[];
|
|
57
|
-
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
58
|
+
/** Props for message actions, such as feedback (positive or negative), copy button, edit message, share, and listen */
|
|
58
59
|
actions?: {
|
|
59
60
|
[key: string]: ActionProps;
|
|
60
61
|
};
|
|
@@ -134,10 +135,16 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
134
135
|
onEditUpdate?: (event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
135
136
|
/** Callback functionf or when edit cancel update button is clicked */
|
|
136
137
|
onEditCancel?: (event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
138
|
+
/** Ref applied to editable message input */
|
|
139
|
+
inputRef?: Ref<HTMLTextAreaElement>;
|
|
137
140
|
/** Props for edit form */
|
|
138
141
|
editFormProps?: FormProps;
|
|
139
142
|
/** Sets message to compact styling. */
|
|
140
143
|
isCompact?: boolean;
|
|
144
|
+
/** Disables markdown parsing for message, allowing only text input */
|
|
145
|
+
isMarkdownDisabled?: boolean;
|
|
146
|
+
/** Allows passing additional props down to markdown parser react-markdown, such as allowedElements and disallowedElements. See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#options for options */
|
|
147
|
+
reactMarkdownProps?: Options;
|
|
141
148
|
}
|
|
142
149
|
export declare const MessageBase: FunctionComponent<MessageProps>;
|
|
143
150
|
declare const Message: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -51,7 +51,7 @@ const ErrorMessage_1 = __importDefault(require("./ErrorMessage/ErrorMessage"));
|
|
|
51
51
|
const MessageInput_1 = __importDefault(require("./MessageInput"));
|
|
52
52
|
const rehypeMoveImagesOutOfParagraphs_1 = require("./Plugins/rehypeMoveImagesOutOfParagraphs");
|
|
53
53
|
const MessageBase = (_a) => {
|
|
54
|
-
var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, editFormProps, isCompact } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "editFormProps", "isCompact"]);
|
|
54
|
+
var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps"]);
|
|
55
55
|
const [messageText, setMessageText] = (0, react_1.useState)(content);
|
|
56
56
|
(0, react_1.useEffect)(() => {
|
|
57
57
|
setMessageText(content);
|
|
@@ -73,48 +73,54 @@ const MessageBase = (_a) => {
|
|
|
73
73
|
// Keep timestamps consistent between Timestamp component and aria-label
|
|
74
74
|
const date = new Date();
|
|
75
75
|
const dateString = timestamp !== null && timestamp !== void 0 ? timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
76
|
+
const handleMarkdown = () => {
|
|
77
|
+
if (isMarkdownDisabled) {
|
|
78
|
+
return ((0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, props, { children: messageText })));
|
|
79
|
+
}
|
|
80
|
+
return ((0, jsx_runtime_1.jsx)(react_markdown_1.default, Object.assign({ components: {
|
|
81
|
+
p: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, props)),
|
|
82
|
+
code: (_a) => {
|
|
83
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
84
|
+
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, props, codeBlockProps, { children: children })));
|
|
85
|
+
},
|
|
86
|
+
h1: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h1 }, props)),
|
|
87
|
+
h2: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h2 }, props)),
|
|
88
|
+
h3: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h3 }, props)),
|
|
89
|
+
h4: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h4 }, props)),
|
|
90
|
+
h5: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h5 }, props)),
|
|
91
|
+
h6: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h6 }, props)),
|
|
92
|
+
blockquote: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.blockquote }, props)),
|
|
93
|
+
ul: (props) => (0, jsx_runtime_1.jsx)(UnorderedListMessage_1.default, Object.assign({}, props)),
|
|
94
|
+
ol: (props) => (0, jsx_runtime_1.jsx)(OrderedListMessage_1.default, Object.assign({}, props)),
|
|
95
|
+
li: (props) => (0, jsx_runtime_1.jsx)(ListItemMessage_1.default, Object.assign({}, props)),
|
|
96
|
+
table: (props) => (0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({}, props, tableProps)),
|
|
97
|
+
tbody: (props) => (0, jsx_runtime_1.jsx)(TbodyMessage_1.default, Object.assign({}, props)),
|
|
98
|
+
thead: (props) => (0, jsx_runtime_1.jsx)(TheadMessage_1.default, Object.assign({}, props)),
|
|
99
|
+
tr: (props) => (0, jsx_runtime_1.jsx)(TrMessage_1.default, Object.assign({}, props)),
|
|
100
|
+
td: (props) => {
|
|
101
|
+
// Conflicts with Td type
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
103
|
+
const { width } = props, rest = __rest(props, ["width"]);
|
|
104
|
+
return (0, jsx_runtime_1.jsx)(TdMessage_1.default, Object.assign({}, rest));
|
|
105
|
+
},
|
|
106
|
+
th: (props) => (0, jsx_runtime_1.jsx)(ThMessage_1.default, Object.assign({}, props)),
|
|
107
|
+
img: (props) => (0, jsx_runtime_1.jsx)(ImageMessage_1.default, Object.assign({}, props)),
|
|
108
|
+
a: (props) => ((0, jsx_runtime_1.jsx)(LinkMessage_1.default, Object.assign({ href: props.href, rel: props.rel, target: props.target }, linkProps, { children: props.children })))
|
|
109
|
+
}, remarkPlugins: [remark_gfm_1.default], rehypePlugins: rehypePlugins }, reactMarkdownProps, { children: messageText })));
|
|
110
|
+
};
|
|
76
111
|
const renderMessage = () => {
|
|
77
112
|
if (isLoading) {
|
|
78
113
|
return (0, jsx_runtime_1.jsx)(MessageLoading_1.default, { loadingWord: loadingWord });
|
|
79
114
|
}
|
|
80
115
|
if (isEditable) {
|
|
81
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), (0, jsx_runtime_1.jsx)(MessageInput_1.default, Object.assign({ content:
|
|
116
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), (0, jsx_runtime_1.jsx)(MessageInput_1.default, Object.assign({ content: messageText, editPlaceholder: editPlaceholder, updateWord: updateWord, cancelWord: cancelWord, onEditUpdate: (event, value) => {
|
|
82
117
|
onEditUpdate && onEditUpdate(event);
|
|
83
118
|
setMessageText(value);
|
|
84
|
-
}, onEditCancel: onEditCancel }, editFormProps))] }));
|
|
119
|
+
}, onEditCancel: onEditCancel, inputRef: inputRef }, editFormProps))] }));
|
|
85
120
|
}
|
|
86
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), error ? (
|
|
87
|
-
p: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, props)),
|
|
88
|
-
code: (_a) => {
|
|
89
|
-
var { children } = _a, props = __rest(_a, ["children"]);
|
|
90
|
-
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, props, codeBlockProps, { children: children })));
|
|
91
|
-
},
|
|
92
|
-
h1: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h1 }, props)),
|
|
93
|
-
h2: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h2 }, props)),
|
|
94
|
-
h3: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h3 }, props)),
|
|
95
|
-
h4: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h4 }, props)),
|
|
96
|
-
h5: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h5 }, props)),
|
|
97
|
-
h6: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h6 }, props)),
|
|
98
|
-
blockquote: (props) => (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.blockquote }, props)),
|
|
99
|
-
ul: (props) => (0, jsx_runtime_1.jsx)(UnorderedListMessage_1.default, Object.assign({}, props)),
|
|
100
|
-
ol: (props) => (0, jsx_runtime_1.jsx)(OrderedListMessage_1.default, Object.assign({}, props)),
|
|
101
|
-
li: (props) => (0, jsx_runtime_1.jsx)(ListItemMessage_1.default, Object.assign({}, props)),
|
|
102
|
-
table: (props) => (0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({}, props, tableProps)),
|
|
103
|
-
tbody: (props) => (0, jsx_runtime_1.jsx)(TbodyMessage_1.default, Object.assign({}, props)),
|
|
104
|
-
thead: (props) => (0, jsx_runtime_1.jsx)(TheadMessage_1.default, Object.assign({}, props)),
|
|
105
|
-
tr: (props) => (0, jsx_runtime_1.jsx)(TrMessage_1.default, Object.assign({}, props)),
|
|
106
|
-
td: (props) => {
|
|
107
|
-
// Conflicts with Td type
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
|
-
const { width } = props, rest = __rest(props, ["width"]);
|
|
110
|
-
return (0, jsx_runtime_1.jsx)(TdMessage_1.default, Object.assign({}, rest));
|
|
111
|
-
},
|
|
112
|
-
th: (props) => (0, jsx_runtime_1.jsx)(ThMessage_1.default, Object.assign({}, props)),
|
|
113
|
-
img: (props) => (0, jsx_runtime_1.jsx)(ImageMessage_1.default, Object.assign({}, props)),
|
|
114
|
-
a: (props) => ((0, jsx_runtime_1.jsx)(LinkMessage_1.default, Object.assign({ href: props.href, rel: props.rel, target: props.target }, linkProps, { children: props.children })))
|
|
115
|
-
}, remarkPlugins: [remark_gfm_1.default], rehypePlugins: rehypePlugins, children: messageText }))] }));
|
|
121
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), error ? (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, Object.assign({}, error)) : handleMarkdown()] }));
|
|
116
122
|
};
|
|
117
|
-
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] }), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-response", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && actions && (0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actions }), userFeedbackForm && (0, jsx_runtime_1.jsx)(UserFeedback_1.default, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && ((0, jsx_runtime_1.jsx)(UserFeedbackComplete_1.default, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
123
|
+
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] }), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-response", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && (0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actions }), userFeedbackForm && (0, jsx_runtime_1.jsx)(UserFeedback_1.default, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && ((0, jsx_runtime_1.jsx)(UserFeedbackComplete_1.default, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
118
124
|
var _a;
|
|
119
125
|
return ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachment", children: (0, jsx_runtime_1.jsx)(FileDetailsLabel_1.default, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
|
|
120
126
|
}) })), !isLoading && endContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: endContent })] })] })] })));
|