@patternfly/chatbot 2.1.0-prerelease.19 → 2.1.0-prerelease.21

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.
Files changed (25) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +4 -1
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.d.ts +1 -0
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +73 -0
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +4 -0
  5. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +2 -2
  6. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.d.ts +1 -0
  7. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +69 -0
  8. package/dist/css/main.css +3 -0
  9. package/dist/css/main.css.map +1 -1
  10. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +4 -1
  11. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.d.ts +1 -0
  12. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +68 -0
  13. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +4 -0
  14. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +2 -2
  15. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.d.ts +1 -0
  16. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +64 -0
  17. package/dist/tsconfig.tsbuildinfo +1 -1
  18. package/package.json +1 -1
  19. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +9 -0
  20. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +1 -1
  21. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx +82 -0
  22. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +4 -1
  23. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +4 -0
  24. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +126 -0
  25. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +10 -1
@@ -16,7 +16,10 @@ const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect
16
16
  const toggle = (toggleRef) => (react_1.default.createElement(react_core_1.Tooltip, { className: "pf-chatbot__tooltip", content: label !== null && label !== void 0 ? label : 'Conversation options', position: "bottom" },
17
17
  react_1.default.createElement(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), role: "menuitem" },
18
18
  react_1.default.createElement(ellipsis_v_icon_1.default, null))));
19
- return (react_1.default.createElement(react_core_1.Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: onSelect, onOpenChange: (isOpen) => setIsOpen(isOpen), popperProps: { position: 'right' }, shouldFocusToggleOnSelect: true, shouldFocusFirstItemOnOpen: true, toggle: toggle }, menuItems));
19
+ return (react_1.default.createElement(react_core_1.Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: (props) => {
20
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(props);
21
+ setIsOpen((prev) => !prev);
22
+ }, onOpenChange: (isOpen) => setIsOpen(isOpen), popperProps: { position: 'right' }, shouldFocusToggleOnSelect: true, shouldFocusFirstItemOnOpen: true, toggle: toggle }, menuItems));
20
23
  };
21
24
  exports.ChatbotConversationHistoryDropdown = ChatbotConversationHistoryDropdown;
22
25
  exports.default = exports.ChatbotConversationHistoryDropdown;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const react_1 = __importDefault(require("react"));
16
+ require("@testing-library/jest-dom");
17
+ const react_core_1 = require("@patternfly/react-core");
18
+ const react_2 = require("@testing-library/react");
19
+ const ChatbotConversationHistoryDropdown_1 = __importDefault(require("./ChatbotConversationHistoryDropdown"));
20
+ describe('ChatbotConversationHistoryDropdown', () => {
21
+ const onSelect = jest.fn();
22
+ const menuItems = (react_1.default.createElement(react_1.default.Fragment, null,
23
+ react_1.default.createElement(react_core_1.DropdownItem, null, "Rename"),
24
+ react_1.default.createElement(react_core_1.DropdownItem, null, "Delete")));
25
+ it('should render the dropdown', () => {
26
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, menuClassName: "custom-class" }));
27
+ expect(react_2.screen.queryByRole('menuitem', { name: /Conversation options/i })).toBeInTheDocument();
28
+ });
29
+ it('should display the dropdown menuItems', () => {
30
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems }));
31
+ const toggle = react_2.screen.queryByRole('menuitem', { name: /Conversation options/i });
32
+ expect(toggle).toBeInTheDocument();
33
+ react_2.fireEvent.click(toggle);
34
+ (0, react_2.waitFor)(() => {
35
+ expect(react_2.screen.getByText('Rename')).toBeInTheDocument();
36
+ expect(react_2.screen.getByText('Delete')).toBeInTheDocument();
37
+ });
38
+ });
39
+ it('should invoke onSelect callback when menuitem is clicked', () => {
40
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
41
+ const toggle = react_2.screen.queryByRole('menuitem', { name: /Conversation options/i });
42
+ react_2.fireEvent.click(toggle);
43
+ react_2.fireEvent.click(react_2.screen.getByText('Rename'));
44
+ expect(onSelect).toHaveBeenCalled();
45
+ });
46
+ it('should toggle the dropdown when menuitem is clicked', () => {
47
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
48
+ const toggle = react_2.screen.queryByRole('menuitem', { name: /Conversation options/i });
49
+ react_2.fireEvent.click(toggle);
50
+ react_2.fireEvent.click(react_2.screen.getByText('Delete'));
51
+ expect(onSelect).toHaveBeenCalled();
52
+ expect(react_2.screen.queryByText('Delete')).not.toBeInTheDocument();
53
+ });
54
+ it('should close the dropdown when user clicks outside', () => {
55
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, onSelect: onSelect }));
56
+ const toggle = react_2.screen.queryByRole('menuitem', { name: /Conversation options/i });
57
+ react_2.fireEvent.click(toggle);
58
+ expect(react_2.screen.queryByText('Delete')).toBeInTheDocument();
59
+ react_2.fireEvent.click(toggle.parentElement);
60
+ expect(react_2.screen.queryByText('Delete')).not.toBeInTheDocument();
61
+ });
62
+ it('should show the tooltip when the user hovers over the toggle button', () => __awaiter(void 0, void 0, void 0, function* () {
63
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, label: "Actions dropdown" }));
64
+ const toggle = react_2.screen.queryByRole('menuitem', { name: /Actions dropdown/i });
65
+ (0, react_2.fireEvent)(toggle, new MouseEvent('mouseenter', {
66
+ bubbles: false,
67
+ cancelable: false
68
+ }));
69
+ yield (0, react_2.waitFor)(() => {
70
+ expect(react_2.screen.queryByText('Actions dropdown')).toBeInTheDocument();
71
+ });
72
+ }));
73
+ });
@@ -47,6 +47,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
47
47
  handleTextInputChange?: (value: string) => void;
48
48
  /** Display mode of chatbot */
49
49
  displayMode: ChatbotDisplayMode;
50
+ /** Reverses the order of the drawer action buttons */
51
+ reverseButtonOrder?: boolean;
52
+ /** Custom test id for the drawer actions */
53
+ drawerActionsTestId?: string;
50
54
  }
51
55
  export declare const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps>;
52
56
  export default ChatbotConversationHistoryNav;
@@ -25,7 +25,7 @@ const react_icons_1 = require("@patternfly/react-icons");
25
25
  const Chatbot_1 = require("../Chatbot/Chatbot");
26
26
  const ChatbotConversationHistoryDropdown_1 = __importDefault(require("./ChatbotConversationHistoryDropdown"));
27
27
  const ChatbotConversationHistoryNav = (_a) => {
28
- var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, newChatButtonText = 'New chat', drawerContent, onNewChat, searchInputPlaceholder = 'Search...', searchInputAriaLabel = 'Filter menu items', handleTextInputChange, displayMode } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode"]);
28
+ var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, newChatButtonText = 'New chat', drawerContent, onNewChat, searchInputPlaceholder = 'Search...', searchInputAriaLabel = 'Filter menu items', handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions' } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId"]);
29
29
  const drawerRef = react_1.default.useRef(null);
30
30
  const onExpand = () => {
31
31
  drawerRef.current && drawerRef.current.focus();
@@ -56,7 +56,7 @@ const ChatbotConversationHistoryNav = (_a) => {
56
56
  react_1.default.createElement(react_core_1.MenuContent, null, buildMenu())));
57
57
  const panelContent = (react_1.default.createElement(react_core_1.DrawerPanelContent, { focusTrap: { enabled: true }, minSize: "384px", maxSize: "384px" },
58
58
  react_1.default.createElement(react_core_1.DrawerHead, null,
59
- react_1.default.createElement(react_core_1.DrawerActions, null,
59
+ react_1.default.createElement(react_core_1.DrawerActions, { "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' },
60
60
  react_1.default.createElement(react_core_1.DrawerCloseButton, { onClick: onDrawerToggle }),
61
61
  onNewChat && react_1.default.createElement(react_core_1.Button, { onClick: onNewChat }, newChatButtonText))),
62
62
  handleTextInputChange && (react_1.default.createElement("div", { className: "pf-chatbot__input" },
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const react_1 = __importDefault(require("react"));
16
+ require("@testing-library/jest-dom");
17
+ const react_2 = require("@testing-library/react");
18
+ const Chatbot_1 = require("../Chatbot/Chatbot");
19
+ const ChatbotConversationHistoryNav_1 = __importDefault(require("./ChatbotConversationHistoryNav"));
20
+ describe('ChatbotConversationHistoryNav', () => {
21
+ const onDrawerToggle = jest.fn();
22
+ const initialConversations = [
23
+ {
24
+ id: '1',
25
+ text: 'Lightspeed documentation'
26
+ }
27
+ ];
28
+ it('should open the conversation history navigation drawer', () => {
29
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations }));
30
+ expect(react_2.screen.queryByText('Lightspeed documentation')).toBeInTheDocument();
31
+ });
32
+ it('should display the conversations for grouped conversations', () => {
33
+ const groupedConversations = {
34
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
35
+ };
36
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: groupedConversations }));
37
+ expect(react_2.screen.queryByText('Chatbot extension')).toBeInTheDocument();
38
+ });
39
+ it('should apply the reversed class when reverseButtonOrder is true', () => {
40
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: true, conversations: initialConversations }));
41
+ expect(react_2.screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
42
+ });
43
+ it('should not apply the reversed class when reverseButtonOrder is false', () => {
44
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: initialConversations }));
45
+ expect(react_2.screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
46
+ });
47
+ it('should invoke handleTextInputChange callback when user searches for conversations', () => {
48
+ const handleSearch = jest.fn();
49
+ const groupedConversations = {
50
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
51
+ };
52
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch }));
53
+ const searchInput = react_2.screen.getByPlaceholderText(/Search/i);
54
+ react_2.fireEvent.change(searchInput, { target: { value: 'Chatbot' } });
55
+ expect(handleSearch).toHaveBeenCalledWith('Chatbot');
56
+ });
57
+ it('should close the drawer when escape key is pressed', () => __awaiter(void 0, void 0, void 0, function* () {
58
+ (0, react_2.render)(react_1.default.createElement(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations }));
59
+ react_2.fireEvent.keyDown(react_2.screen.getByPlaceholderText(/Search/i), {
60
+ key: 'Escape',
61
+ code: 'Escape',
62
+ keyCode: 27,
63
+ charCode: 27
64
+ });
65
+ (0, react_2.waitFor)(() => {
66
+ expect(react_2.screen.queryByText('Lightspeed documentation')).not.toBeInTheDocument();
67
+ });
68
+ }));
69
+ });
package/dist/css/main.css CHANGED
@@ -223,6 +223,9 @@ html.pf-chatbot-allow--docked {
223
223
  width: 100%;
224
224
  height: 100%;
225
225
  }
226
+ .pf-chatbot__history.pf-v6-c-drawer .pf-v6-c-drawer__actions--reversed {
227
+ flex-direction: row-reverse;
228
+ }
226
229
  .pf-chatbot__history.pf-v6-c-drawer .pf-v6-c-drawer__close .pf-v6-c-button {
227
230
  width: var(--pf-t--global--spacer--2xl);
228
231
  height: var(--pf-t--global--spacer--2xl);
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;ACvFF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;IACA;;;ACfJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAQF;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;AC9JN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;;;AAUF;EACE;;AAGJ;EACE;;;AChDJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;AAEF;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AC1IF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;ACxEN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AC/BF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;;AAQR;EACE;EACA;EACA;;;ACnHF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AD5CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AC3CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;AHnBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AI9CN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;;ACbN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EACE;;;AAKN;EACE;IACE;IACA;;EAEF;IACE;IACA;;;ACvBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;;;ACTJ;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACvEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACzCJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;AD5BN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;AE3CJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;;ACrBR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;ACJF;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;ACvFF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;IACA;;;ACfJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAQF;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;AClKN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;;;AAUF;EACE;;AAGJ;EACE;;;AChDJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;AAEF;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AC1IF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;ACxEN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AC/BF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;;AAQR;EACE;EACA;EACA;;;ACnHF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AD5CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AC3CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;AHnBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AI9CN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;;ACbN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EACE;;;AAKN;EACE;IACE;IACA;;EAEF;IACE;IACA;;;ACvBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;;;ACTJ;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACvEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACzCJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;AD5BN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;AE3CJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;;ACrBR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;ACJF;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
@@ -10,6 +10,9 @@ export const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, o
10
10
  const toggle = (toggleRef) => (React.createElement(Tooltip, { className: "pf-chatbot__tooltip", content: label !== null && label !== void 0 ? label : 'Conversation options', position: "bottom" },
11
11
  React.createElement(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), role: "menuitem" },
12
12
  React.createElement(EllipsisIcon, null))));
13
- return (React.createElement(Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: onSelect, onOpenChange: (isOpen) => setIsOpen(isOpen), popperProps: { position: 'right' }, shouldFocusToggleOnSelect: true, shouldFocusFirstItemOnOpen: true, toggle: toggle }, menuItems));
13
+ return (React.createElement(Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: (props) => {
14
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(props);
15
+ setIsOpen((prev) => !prev);
16
+ }, onOpenChange: (isOpen) => setIsOpen(isOpen), popperProps: { position: 'right' }, shouldFocusToggleOnSelect: true, shouldFocusFirstItemOnOpen: true, toggle: toggle }, menuItems));
14
17
  };
15
18
  export default ChatbotConversationHistoryDropdown;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,68 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from 'react';
11
+ import '@testing-library/jest-dom';
12
+ import { DropdownItem } from '@patternfly/react-core';
13
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
14
+ import ChatbotConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
15
+ describe('ChatbotConversationHistoryDropdown', () => {
16
+ const onSelect = jest.fn();
17
+ const menuItems = (React.createElement(React.Fragment, null,
18
+ React.createElement(DropdownItem, null, "Rename"),
19
+ React.createElement(DropdownItem, null, "Delete")));
20
+ it('should render the dropdown', () => {
21
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems, menuClassName: "custom-class" }));
22
+ expect(screen.queryByRole('menuitem', { name: /Conversation options/i })).toBeInTheDocument();
23
+ });
24
+ it('should display the dropdown menuItems', () => {
25
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems }));
26
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i });
27
+ expect(toggle).toBeInTheDocument();
28
+ fireEvent.click(toggle);
29
+ waitFor(() => {
30
+ expect(screen.getByText('Rename')).toBeInTheDocument();
31
+ expect(screen.getByText('Delete')).toBeInTheDocument();
32
+ });
33
+ });
34
+ it('should invoke onSelect callback when menuitem is clicked', () => {
35
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems, onSelect: onSelect }));
36
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i });
37
+ fireEvent.click(toggle);
38
+ fireEvent.click(screen.getByText('Rename'));
39
+ expect(onSelect).toHaveBeenCalled();
40
+ });
41
+ it('should toggle the dropdown when menuitem is clicked', () => {
42
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems, onSelect: onSelect }));
43
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i });
44
+ fireEvent.click(toggle);
45
+ fireEvent.click(screen.getByText('Delete'));
46
+ expect(onSelect).toHaveBeenCalled();
47
+ expect(screen.queryByText('Delete')).not.toBeInTheDocument();
48
+ });
49
+ it('should close the dropdown when user clicks outside', () => {
50
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems, onSelect: onSelect }));
51
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i });
52
+ fireEvent.click(toggle);
53
+ expect(screen.queryByText('Delete')).toBeInTheDocument();
54
+ fireEvent.click(toggle.parentElement);
55
+ expect(screen.queryByText('Delete')).not.toBeInTheDocument();
56
+ });
57
+ it('should show the tooltip when the user hovers over the toggle button', () => __awaiter(void 0, void 0, void 0, function* () {
58
+ render(React.createElement(ChatbotConversationHistoryDropdown, { menuItems: menuItems, label: "Actions dropdown" }));
59
+ const toggle = screen.queryByRole('menuitem', { name: /Actions dropdown/i });
60
+ fireEvent(toggle, new MouseEvent('mouseenter', {
61
+ bubbles: false,
62
+ cancelable: false
63
+ }));
64
+ yield waitFor(() => {
65
+ expect(screen.queryByText('Actions dropdown')).toBeInTheDocument();
66
+ });
67
+ }));
68
+ });
@@ -47,6 +47,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
47
47
  handleTextInputChange?: (value: string) => void;
48
48
  /** Display mode of chatbot */
49
49
  displayMode: ChatbotDisplayMode;
50
+ /** Reverses the order of the drawer action buttons */
51
+ reverseButtonOrder?: boolean;
52
+ /** Custom test id for the drawer actions */
53
+ drawerActionsTestId?: string;
50
54
  }
51
55
  export declare const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps>;
52
56
  export default ChatbotConversationHistoryNav;
@@ -19,7 +19,7 @@ import { OutlinedCommentAltIcon } from '@patternfly/react-icons';
19
19
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
20
20
  import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
21
21
  export const ChatbotConversationHistoryNav = (_a) => {
22
- var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, newChatButtonText = 'New chat', drawerContent, onNewChat, searchInputPlaceholder = 'Search...', searchInputAriaLabel = 'Filter menu items', handleTextInputChange, displayMode } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode"]);
22
+ var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, newChatButtonText = 'New chat', drawerContent, onNewChat, searchInputPlaceholder = 'Search...', searchInputAriaLabel = 'Filter menu items', handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions' } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId"]);
23
23
  const drawerRef = React.useRef(null);
24
24
  const onExpand = () => {
25
25
  drawerRef.current && drawerRef.current.focus();
@@ -50,7 +50,7 @@ export const ChatbotConversationHistoryNav = (_a) => {
50
50
  React.createElement(MenuContent, null, buildMenu())));
51
51
  const panelContent = (React.createElement(DrawerPanelContent, { focusTrap: { enabled: true }, minSize: "384px", maxSize: "384px" },
52
52
  React.createElement(DrawerHead, null,
53
- React.createElement(DrawerActions, null,
53
+ React.createElement(DrawerActions, { "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' },
54
54
  React.createElement(DrawerCloseButton, { onClick: onDrawerToggle }),
55
55
  onNewChat && React.createElement(Button, { onClick: onNewChat }, newChatButtonText))),
56
56
  handleTextInputChange && (React.createElement("div", { className: "pf-chatbot__input" },
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,64 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from 'react';
11
+ import '@testing-library/jest-dom';
12
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
13
+ import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
14
+ import ChatbotConversationHistoryNav from './ChatbotConversationHistoryNav';
15
+ describe('ChatbotConversationHistoryNav', () => {
16
+ const onDrawerToggle = jest.fn();
17
+ const initialConversations = [
18
+ {
19
+ id: '1',
20
+ text: 'Lightspeed documentation'
21
+ }
22
+ ];
23
+ it('should open the conversation history navigation drawer', () => {
24
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations }));
25
+ expect(screen.queryByText('Lightspeed documentation')).toBeInTheDocument();
26
+ });
27
+ it('should display the conversations for grouped conversations', () => {
28
+ const groupedConversations = {
29
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
30
+ };
31
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: groupedConversations }));
32
+ expect(screen.queryByText('Chatbot extension')).toBeInTheDocument();
33
+ });
34
+ it('should apply the reversed class when reverseButtonOrder is true', () => {
35
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: true, conversations: initialConversations }));
36
+ expect(screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
37
+ });
38
+ it('should not apply the reversed class when reverseButtonOrder is false', () => {
39
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: initialConversations }));
40
+ expect(screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
41
+ });
42
+ it('should invoke handleTextInputChange callback when user searches for conversations', () => {
43
+ const handleSearch = jest.fn();
44
+ const groupedConversations = {
45
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
46
+ };
47
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch }));
48
+ const searchInput = screen.getByPlaceholderText(/Search/i);
49
+ fireEvent.change(searchInput, { target: { value: 'Chatbot' } });
50
+ expect(handleSearch).toHaveBeenCalledWith('Chatbot');
51
+ });
52
+ it('should close the drawer when escape key is pressed', () => __awaiter(void 0, void 0, void 0, function* () {
53
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations }));
54
+ fireEvent.keyDown(screen.getByPlaceholderText(/Search/i), {
55
+ key: 'Escape',
56
+ code: 'Escape',
57
+ keyCode: 27,
58
+ charCode: 27
59
+ });
60
+ waitFor(() => {
61
+ expect(screen.queryByText('Lightspeed documentation')).not.toBeInTheDocument();
62
+ });
63
+ }));
64
+ });
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.1.0-prerelease.19",
3
+ "version": "2.1.0-prerelease.21",
4
4
  "description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -33,6 +33,7 @@ const initialConversations: { [key: string]: Conversation[] } = {
33
33
 
34
34
  export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
35
35
  const [isOpen, setIsOpen] = React.useState(true);
36
+ const [isButtonOrderReversed, setIsbuttonOrderReversed] = React.useState(false);
36
37
  const [conversations, setConversations] = React.useState<Conversation[] | { [key: string]: Conversation[] }>(
37
38
  initialConversations
38
39
  );
@@ -66,6 +67,13 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
66
67
  id="drawer-visible"
67
68
  name="drawer-visible"
68
69
  />
70
+ <Checkbox
71
+ label="Reverse action buttons"
72
+ isChecked={isButtonOrderReversed}
73
+ onChange={() => setIsbuttonOrderReversed(!isButtonOrderReversed)}
74
+ id="drawer-actions-visible"
75
+ name="drawer-actions-visible"
76
+ ></Checkbox>
69
77
  <ChatbotConversationHistoryNav
70
78
  displayMode={displayMode}
71
79
  onDrawerToggle={() => setIsOpen(!isOpen)}
@@ -77,6 +85,7 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
77
85
  onNewChat={() => {
78
86
  setIsOpen(!isOpen);
79
87
  }}
88
+ reverseButtonOrder={isButtonOrderReversed}
80
89
  handleTextInputChange={(value: string) => {
81
90
  if (value === '') {
82
91
  setConversations(initialConversations);
@@ -321,7 +321,7 @@ In the conversation history drawer, users can search previous chatbot conversati
321
321
 
322
322
  They can also start new conversations via a "New chat" button. To customize the button label, use `newChatButtonText`.
323
323
 
324
- Both the search input field and "New chat" buttons are optional.
324
+ Both the search input field and "New chat" buttons are optional. The `reverseButtonOrder` prop allows you to invert the positions of the Close and "New chat" buttons within the drawer when set to `true`.
325
325
 
326
326
  ```js file="./ChatbotHeaderDrawer.tsx"
327
327
 
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import { DropdownItem } from '@patternfly/react-core';
4
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
5
+ import ChatbotConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
6
+
7
+ describe('ChatbotConversationHistoryDropdown', () => {
8
+ const onSelect = jest.fn();
9
+ const menuItems = (
10
+ <>
11
+ <DropdownItem>Rename</DropdownItem>
12
+ <DropdownItem>Delete</DropdownItem>
13
+ </>
14
+ );
15
+
16
+ it('should render the dropdown', () => {
17
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} menuClassName="custom-class" />);
18
+ expect(screen.queryByRole('menuitem', { name: /Conversation options/i })).toBeInTheDocument();
19
+ });
20
+
21
+ it('should display the dropdown menuItems', () => {
22
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} />);
23
+
24
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i })!;
25
+
26
+ expect(toggle).toBeInTheDocument();
27
+ fireEvent.click(toggle);
28
+
29
+ waitFor(() => {
30
+ expect(screen.getByText('Rename')).toBeInTheDocument();
31
+ expect(screen.getByText('Delete')).toBeInTheDocument();
32
+ });
33
+ });
34
+
35
+ it('should invoke onSelect callback when menuitem is clicked', () => {
36
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} onSelect={onSelect} />);
37
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i })!;
38
+ fireEvent.click(toggle);
39
+ fireEvent.click(screen.getByText('Rename'));
40
+
41
+ expect(onSelect).toHaveBeenCalled();
42
+ });
43
+
44
+ it('should toggle the dropdown when menuitem is clicked', () => {
45
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} onSelect={onSelect} />);
46
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i })!;
47
+ fireEvent.click(toggle);
48
+ fireEvent.click(screen.getByText('Delete'));
49
+
50
+ expect(onSelect).toHaveBeenCalled();
51
+
52
+ expect(screen.queryByText('Delete')).not.toBeInTheDocument();
53
+ });
54
+
55
+ it('should close the dropdown when user clicks outside', () => {
56
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} onSelect={onSelect} />);
57
+ const toggle = screen.queryByRole('menuitem', { name: /Conversation options/i })!;
58
+ fireEvent.click(toggle);
59
+
60
+ expect(screen.queryByText('Delete')).toBeInTheDocument();
61
+ fireEvent.click(toggle.parentElement!);
62
+
63
+ expect(screen.queryByText('Delete')).not.toBeInTheDocument();
64
+ });
65
+
66
+ it('should show the tooltip when the user hovers over the toggle button', async () => {
67
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} label="Actions dropdown" />);
68
+ const toggle = screen.queryByRole('menuitem', { name: /Actions dropdown/i })!;
69
+
70
+ fireEvent(
71
+ toggle,
72
+ new MouseEvent('mouseenter', {
73
+ bubbles: false,
74
+ cancelable: false
75
+ })
76
+ );
77
+
78
+ await waitFor(() => {
79
+ expect(screen.queryByText('Actions dropdown')).toBeInTheDocument();
80
+ });
81
+ });
82
+ });
@@ -47,7 +47,10 @@ export const ChatbotConversationHistoryDropdown: React.FunctionComponent<Chatbot
47
47
  <Dropdown
48
48
  className={`pf-chatbot__selections ${menuClassName ?? ''}`}
49
49
  isOpen={isOpen}
50
- onSelect={onSelect}
50
+ onSelect={(props) => {
51
+ onSelect?.(props);
52
+ setIsOpen((prev) => !prev);
53
+ }}
51
54
  onOpenChange={(isOpen) => setIsOpen(isOpen)}
52
55
  popperProps={{ position: 'right' }}
53
56
  shouldFocusToggleOnSelect
@@ -93,6 +93,10 @@
93
93
  height: 100%;
94
94
  }
95
95
 
96
+ .pf-v6-c-drawer__actions--reversed {
97
+ flex-direction: row-reverse;
98
+ }
99
+
96
100
  // Close drawer
97
101
  .pf-v6-c-drawer__close {
98
102
  .pf-v6-c-button {
@@ -0,0 +1,126 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
4
+
5
+ import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
6
+ import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';
7
+
8
+ describe('ChatbotConversationHistoryNav', () => {
9
+ const onDrawerToggle = jest.fn();
10
+
11
+ const initialConversations: Conversation[] = [
12
+ {
13
+ id: '1',
14
+ text: 'Lightspeed documentation'
15
+ }
16
+ ];
17
+
18
+ it('should open the conversation history navigation drawer', () => {
19
+ render(
20
+ <ChatbotConversationHistoryNav
21
+ onDrawerToggle={onDrawerToggle}
22
+ isDrawerOpen={true}
23
+ displayMode={ChatbotDisplayMode.fullscreen}
24
+ setIsDrawerOpen={jest.fn()}
25
+ conversations={initialConversations}
26
+ />
27
+ );
28
+ expect(screen.queryByText('Lightspeed documentation')).toBeInTheDocument();
29
+ });
30
+
31
+ it('should display the conversations for grouped conversations', () => {
32
+ const groupedConversations: { [key: string]: Conversation[] } = {
33
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
34
+ };
35
+
36
+ render(
37
+ <ChatbotConversationHistoryNav
38
+ onDrawerToggle={onDrawerToggle}
39
+ isDrawerOpen={true}
40
+ displayMode={ChatbotDisplayMode.fullscreen}
41
+ setIsDrawerOpen={jest.fn()}
42
+ conversations={groupedConversations}
43
+ />
44
+ );
45
+ expect(screen.queryByText('Chatbot extension')).toBeInTheDocument();
46
+ });
47
+
48
+ it('should apply the reversed class when reverseButtonOrder is true', () => {
49
+ render(
50
+ <ChatbotConversationHistoryNav
51
+ onDrawerToggle={onDrawerToggle}
52
+ isDrawerOpen={true}
53
+ displayMode={ChatbotDisplayMode.fullscreen}
54
+ setIsDrawerOpen={jest.fn()}
55
+ reverseButtonOrder
56
+ conversations={initialConversations}
57
+ />
58
+ );
59
+
60
+ expect(screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
61
+ });
62
+
63
+ it('should not apply the reversed class when reverseButtonOrder is false', () => {
64
+ render(
65
+ <ChatbotConversationHistoryNav
66
+ onDrawerToggle={onDrawerToggle}
67
+ isDrawerOpen={true}
68
+ displayMode={ChatbotDisplayMode.fullscreen}
69
+ setIsDrawerOpen={jest.fn()}
70
+ reverseButtonOrder={false}
71
+ conversations={initialConversations}
72
+ />
73
+ );
74
+ expect(screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
75
+ });
76
+
77
+ it('should invoke handleTextInputChange callback when user searches for conversations', () => {
78
+ const handleSearch = jest.fn();
79
+ const groupedConversations: { [key: string]: Conversation[] } = {
80
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
81
+ };
82
+
83
+ render(
84
+ <ChatbotConversationHistoryNav
85
+ onDrawerToggle={onDrawerToggle}
86
+ isDrawerOpen={true}
87
+ displayMode={ChatbotDisplayMode.fullscreen}
88
+ setIsDrawerOpen={jest.fn()}
89
+ reverseButtonOrder={false}
90
+ conversations={groupedConversations}
91
+ handleTextInputChange={handleSearch}
92
+ />
93
+ );
94
+
95
+ const searchInput = screen.getByPlaceholderText(/Search/i);
96
+
97
+ fireEvent.change(searchInput, { target: { value: 'Chatbot' } });
98
+
99
+ expect(handleSearch).toHaveBeenCalledWith('Chatbot');
100
+ });
101
+
102
+ it('should close the drawer when escape key is pressed', async () => {
103
+ render(
104
+ <ChatbotConversationHistoryNav
105
+ onDrawerToggle={onDrawerToggle}
106
+ isDrawerOpen={true}
107
+ displayMode={ChatbotDisplayMode.fullscreen}
108
+ setIsDrawerOpen={jest.fn()}
109
+ reverseButtonOrder={false}
110
+ handleTextInputChange={jest.fn()}
111
+ conversations={initialConversations}
112
+ />
113
+ );
114
+
115
+ fireEvent.keyDown(screen.getByPlaceholderText(/Search/i), {
116
+ key: 'Escape',
117
+ code: 'Escape',
118
+ keyCode: 27,
119
+ charCode: 27
120
+ });
121
+
122
+ waitFor(() => {
123
+ expect(screen.queryByText('Lightspeed documentation')).not.toBeInTheDocument();
124
+ });
125
+ });
126
+ });
@@ -72,6 +72,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
72
72
  handleTextInputChange?: (value: string) => void;
73
73
  /** Display mode of chatbot */
74
74
  displayMode: ChatbotDisplayMode;
75
+ /** Reverses the order of the drawer action buttons */
76
+ reverseButtonOrder?: boolean;
77
+ /** Custom test id for the drawer actions */
78
+ drawerActionsTestId?: string;
75
79
  }
76
80
 
77
81
  export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps> = ({
@@ -88,6 +92,8 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
88
92
  searchInputAriaLabel = 'Filter menu items',
89
93
  handleTextInputChange,
90
94
  displayMode,
95
+ reverseButtonOrder = false,
96
+ drawerActionsTestId = 'chatbot-nav-drawer-actions',
91
97
  ...props
92
98
  }: ChatbotConversationHistoryNavProps) => {
93
99
  const drawerRef = React.useRef<HTMLDivElement>(null);
@@ -161,7 +167,10 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
161
167
  const panelContent = (
162
168
  <DrawerPanelContent focusTrap={{ enabled: true }} minSize="384px" maxSize="384px">
163
169
  <DrawerHead>
164
- <DrawerActions>
170
+ <DrawerActions
171
+ data-testid={drawerActionsTestId}
172
+ className={reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : ''}
173
+ >
165
174
  <DrawerCloseButton onClick={onDrawerToggle} />
166
175
  {onNewChat && <Button onClick={onNewChat}>{newChatButtonText}</Button>}
167
176
  </DrawerActions>