@patternfly/chatbot 2.2.0-prerelease.26 → 2.2.0-prerelease.27

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 (24) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +8 -1
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +22 -10
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +60 -0
  4. package/dist/cjs/ChatbotConversationHistoryNav/EmptyState.d.ts +11 -0
  5. package/dist/cjs/ChatbotConversationHistoryNav/EmptyState.js +29 -0
  6. package/dist/cjs/ChatbotConversationHistoryNav/LoadingState.d.ts +4 -0
  7. package/dist/cjs/ChatbotConversationHistoryNav/LoadingState.js +45 -0
  8. package/dist/css/main.css +14 -0
  9. package/dist/css/main.css.map +1 -1
  10. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +8 -1
  11. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +22 -10
  12. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +60 -0
  13. package/dist/esm/ChatbotConversationHistoryNav/EmptyState.d.ts +11 -0
  14. package/dist/esm/ChatbotConversationHistoryNav/EmptyState.js +22 -0
  15. package/dist/esm/ChatbotConversationHistoryNav/LoadingState.d.ts +4 -0
  16. package/dist/esm/ChatbotConversationHistoryNav/LoadingState.js +38 -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 +34 -1
  20. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
  21. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +130 -0
  22. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +56 -21
  23. package/src/ChatbotConversationHistoryNav/EmptyState.tsx +44 -0
  24. package/src/ChatbotConversationHistoryNav/LoadingState.tsx +38 -0
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
- import { DrawerProps, MenuItemProps, MenuProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps } from '@patternfly/react-core';
2
+ import { DrawerProps, MenuItemProps, MenuProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps } from '@patternfly/react-core';
3
3
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
4
+ import { HistoryEmptyStateProps } from './EmptyState';
4
5
  export interface Conversation {
5
6
  /** Conversation id */
6
7
  id: string;
@@ -69,6 +70,12 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
69
70
  drawerCloseButtonProps?: DrawerCloseButtonProps;
70
71
  /** Additional props appleid to drawer panel body */
71
72
  drawerPanelBodyProps?: DrawerPanelBodyProps;
73
+ /** Whether to show drawer loading state */
74
+ isLoading?: boolean;
75
+ /** Additional props for loading state */
76
+ loadingState?: SkeletonProps;
77
+ /** Content to show in error state. Error state will appear once content is passed in. */
78
+ errorState?: HistoryEmptyStateProps;
72
79
  }
73
80
  export declare const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps>;
74
81
  export default ChatbotConversationHistoryNav;
@@ -24,8 +24,10 @@ const react_core_1 = require("@patternfly/react-core");
24
24
  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
+ const LoadingState_1 = __importDefault(require("./LoadingState"));
28
+ const EmptyState_1 = __importDefault(require("./EmptyState"));
27
29
  const ChatbotConversationHistoryNav = (_a) => {
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', menuProps, drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "menuProps", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps"]);
30
+ 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', menuProps, drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, isLoading, loadingState, errorState } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "menuProps", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "isLoading", "loadingState", "errorState"]);
29
31
  const drawerRef = react_1.default.useRef(null);
30
32
  const onExpand = () => {
31
33
  drawerRef.current && drawerRef.current.focus();
@@ -52,16 +54,26 @@ const ChatbotConversationHistoryNav = (_a) => {
52
54
  // Menu Content
53
55
  // - Consumers should pass an array to <Chatbot> of the list of conversations
54
56
  // - Groups could be optional, but items need to be ordered by date
55
- const menuContent = (react_1.default.createElement(react_core_1.Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps),
56
- react_1.default.createElement(react_core_1.MenuContent, null, buildMenu())));
57
- const panelContent = (react_1.default.createElement(react_core_1.DrawerPanelContent, Object.assign({ focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps),
58
- react_1.default.createElement(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps),
59
- react_1.default.createElement(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps),
60
- react_1.default.createElement(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)),
61
- onNewChat && react_1.default.createElement(react_core_1.Button, { onClick: onNewChat }, newChatButtonText))),
57
+ const renderMenuContent = () => {
58
+ if (errorState) {
59
+ return react_1.default.createElement(EmptyState_1.default, Object.assign({}, errorState));
60
+ }
61
+ return (react_1.default.createElement(react_core_1.Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps),
62
+ react_1.default.createElement(react_core_1.MenuContent, null, buildMenu())));
63
+ };
64
+ const renderDrawerContent = () => (react_1.default.createElement(react_1.default.Fragment, null,
62
65
  handleTextInputChange && (react_1.default.createElement("div", { className: "pf-chatbot__input" },
63
66
  react_1.default.createElement(react_core_1.SearchInput, { "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }))),
64
- react_1.default.createElement(react_core_1.DrawerPanelBody, Object.assign({}, drawerPanelBodyProps), menuContent)));
67
+ react_1.default.createElement(react_core_1.DrawerPanelBody, Object.assign({}, drawerPanelBodyProps), renderMenuContent())));
68
+ const renderPanelContent = () => {
69
+ const drawer = (react_1.default.createElement(react_1.default.Fragment, null,
70
+ react_1.default.createElement(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps),
71
+ react_1.default.createElement(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps),
72
+ react_1.default.createElement(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)),
73
+ onNewChat && react_1.default.createElement(react_core_1.Button, { onClick: onNewChat }, newChatButtonText))),
74
+ isLoading ? react_1.default.createElement(LoadingState_1.default, Object.assign({}, loadingState)) : renderDrawerContent()));
75
+ return (react_1.default.createElement(react_core_1.DrawerPanelContent, Object.assign({ "aria-live": "polite", focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps), drawer));
76
+ };
65
77
  // An onKeyDown property must be passed to the Drawer component to handle closing
66
78
  // the drawer panel and deactivating the focus trap via the Escape key.
67
79
  const onEscape = (event) => {
@@ -73,7 +85,7 @@ const ChatbotConversationHistoryNav = (_a) => {
73
85
  }
74
86
  };
75
87
  return (react_1.default.createElement(react_core_1.Drawer, Object.assign({ className: "pf-chatbot__history", isExpanded: isDrawerOpen, onExpand: onExpand, position: "start", onKeyDown: onEscape, isInline: displayMode === Chatbot_1.ChatbotDisplayMode.fullscreen || displayMode === Chatbot_1.ChatbotDisplayMode.embedded }, props),
76
- react_1.default.createElement(react_core_1.DrawerContent, Object.assign({ panelContent: panelContent }, drawerContentProps),
88
+ react_1.default.createElement(react_core_1.DrawerContent, Object.assign({ panelContent: renderPanelContent() }, drawerContentProps),
77
89
  react_1.default.createElement(react_core_1.DrawerContentBody, Object.assign({}, drawerContentBodyProps),
78
90
  react_1.default.createElement(react_1.default.Fragment, null,
79
91
  react_1.default.createElement("div", { className: `${isDrawerOpen && (displayMode === Chatbot_1.ChatbotDisplayMode.default || displayMode === Chatbot_1.ChatbotDisplayMode.docked) ? 'pf-v6-c-backdrop pf-chatbot__drawer-backdrop' : undefined} ` }),
@@ -17,6 +17,33 @@ require("@testing-library/jest-dom");
17
17
  const react_2 = require("@testing-library/react");
18
18
  const Chatbot_1 = require("../Chatbot/Chatbot");
19
19
  const ChatbotConversationHistoryNav_1 = __importDefault(require("./ChatbotConversationHistoryNav"));
20
+ const react_core_1 = require("@patternfly/react-core");
21
+ const ERROR = {
22
+ bodyText: (react_1.default.createElement(react_1.default.Fragment, null,
23
+ "To try again, check your connection and reload this page. If the issue persists,",
24
+ ' ',
25
+ react_1.default.createElement("a", { href: "" }, "contact the support team"),
26
+ ".")),
27
+ buttonText: 'Reload',
28
+ buttonIcon: react_1.default.createElement(react_core_1.Spinner, { size: "sm" }),
29
+ hasButton: true,
30
+ titleText: 'Could not load chat history',
31
+ status: react_core_1.EmptyStateStatus.danger,
32
+ onClick: () => alert('Clicked Reload')
33
+ };
34
+ const ERROR_WITHOUT_BUTTON = {
35
+ bodyText: (react_1.default.createElement(react_1.default.Fragment, null,
36
+ "To try again, check your connection and reload this page. If the issue persists,",
37
+ ' ',
38
+ react_1.default.createElement("a", { href: "" }, "contact the support team"),
39
+ ".")),
40
+ buttonText: 'Reload',
41
+ buttonIcon: react_1.default.createElement(react_core_1.Spinner, { size: "sm" }),
42
+ hasButton: false,
43
+ titleText: 'Could not load chat history',
44
+ status: react_core_1.EmptyStateStatus.danger,
45
+ onClick: () => alert('Clicked Reload')
46
+ };
20
47
  describe('ChatbotConversationHistoryNav', () => {
21
48
  const onDrawerToggle = jest.fn();
22
49
  const initialConversations = [
@@ -102,4 +129,37 @@ describe('ChatbotConversationHistoryNav', () => {
102
129
  const element = container.querySelector('.test');
103
130
  expect(element).toBeInTheDocument();
104
131
  });
132
+ it('should show loading state if triggered', () => {
133
+ (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, isLoading: true }));
134
+ expect(react_2.screen.getByRole('dialog', { name: /Loading chatbot conversation history/i })).toBeTruthy();
135
+ expect(react_2.screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
136
+ });
137
+ it('should pass alternative aria label to loading state', () => {
138
+ (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, isLoading: true, loadingState: { screenreaderText: 'I am a test' } }));
139
+ expect(react_2.screen.getByRole('dialog', { name: /I am a test/i })).toBeTruthy();
140
+ });
141
+ it('should accept errorState', () => {
142
+ (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, errorState: ERROR }));
143
+ expect(react_2.screen.getByRole('dialog', {
144
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team . Loading... Reload/i
145
+ })).toBeTruthy();
146
+ expect(react_2.screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
147
+ expect(react_2.screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
148
+ expect(react_2.screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
149
+ expect(react_2.screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
150
+ });
151
+ it('should accept errorState without button', () => {
152
+ (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, errorState: ERROR_WITHOUT_BUTTON }));
153
+ expect(react_2.screen.getByRole('dialog', {
154
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team ./i
155
+ })).toBeTruthy();
156
+ expect(react_2.screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
157
+ expect(react_2.screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
158
+ expect(react_2.screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
159
+ expect(react_2.screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
160
+ });
161
+ it('should show loading state over error state if both are supplied', () => {
162
+ (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, isLoading: true, errorState: ERROR }));
163
+ expect(react_2.screen.getByRole('dialog', { name: /Loading/i })).toBeTruthy();
164
+ });
105
165
  });
@@ -0,0 +1,11 @@
1
+ import { EmptyStateProps } from '@patternfly/react-core';
2
+ import React from 'react';
3
+ export interface HistoryEmptyStateProps extends EmptyStateProps {
4
+ onClick?: () => void;
5
+ bodyText?: string | React.ReactNode;
6
+ buttonText?: string;
7
+ buttonIcon?: React.ReactNode;
8
+ hasButton?: boolean;
9
+ }
10
+ export declare const HistoryEmptyState: React.FunctionComponent<HistoryEmptyStateProps>;
11
+ export default HistoryEmptyState;
@@ -0,0 +1,29 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.HistoryEmptyState = void 0;
18
+ const react_core_1 = require("@patternfly/react-core");
19
+ const react_1 = __importDefault(require("react"));
20
+ const HistoryEmptyState = (_a) => {
21
+ var { bodyText, buttonIcon, buttonText, status, titleText, headingLevel, onClick, hasButton = false } = _a, props = __rest(_a, ["bodyText", "buttonIcon", "buttonText", "status", "titleText", "headingLevel", "onClick", "hasButton"]);
22
+ return (react_1.default.createElement(react_core_1.EmptyState, Object.assign({ status: status, titleText: titleText, headingLevel: headingLevel }, props),
23
+ react_1.default.createElement(react_core_1.EmptyStateBody, null, bodyText),
24
+ hasButton && (react_1.default.createElement(react_core_1.EmptyStateFooter, null,
25
+ react_1.default.createElement(react_core_1.EmptyStateActions, null,
26
+ react_1.default.createElement(react_core_1.Button, { icon: buttonIcon, variant: "secondary", onClick: onClick }, buttonText))))));
27
+ };
28
+ exports.HistoryEmptyState = HistoryEmptyState;
29
+ exports.default = exports.HistoryEmptyState;
@@ -0,0 +1,4 @@
1
+ import { SkeletonProps } from '@patternfly/react-core';
2
+ import React from 'react';
3
+ export declare const LoadingState: React.FunctionComponent<SkeletonProps>;
4
+ export default LoadingState;
@@ -0,0 +1,45 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.LoadingState = void 0;
18
+ const react_core_1 = require("@patternfly/react-core");
19
+ const react_1 = __importDefault(require("react"));
20
+ const LoadingState = (_a) => {
21
+ var { screenreaderText } = _a, rest = __rest(_a, ["screenreaderText"]);
22
+ return (react_1.default.createElement("div", { className: "pf-chatbot__history-loading" },
23
+ react_1.default.createElement("div", { className: "pf-chatbot__history-loading-block" },
24
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ screenreaderText: screenreaderText !== null && screenreaderText !== void 0 ? screenreaderText : 'Loading chatbot conversation history', fontSize: "3xl" }, rest))),
25
+ react_1.default.createElement("div", { className: "pf-chatbot__history-loading-block" },
26
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
27
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
28
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
29
+ react_1.default.createElement("div", { className: "pf-chatbot__history-loading-block" },
30
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
31
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
32
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
33
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
34
+ react_1.default.createElement("div", { className: "pf-chatbot__history-loading-block" },
35
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
36
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
37
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
38
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
39
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
40
+ react_1.default.createElement("div", { className: "pf-chatbot__history-loading-block" },
41
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
42
+ react_1.default.createElement(react_core_1.Skeleton, Object.assign({ fontSize: "3xl" }, rest)))));
43
+ };
44
+ exports.LoadingState = LoadingState;
45
+ exports.default = exports.LoadingState;
package/dist/css/main.css CHANGED
@@ -308,6 +308,20 @@
308
308
  border-radius: unset;
309
309
  }
310
310
 
311
+ .pf-chatbot__history-loading {
312
+ display: flex;
313
+ padding: var(--pf-t--global--spacer--lg);
314
+ flex-direction: column;
315
+ gap: var(--pf-t--global--spacer--lg);
316
+ }
317
+
318
+ .pf-chatbot__history-loading-block {
319
+ display: flex;
320
+ flex-direction: column;
321
+ gap: var(--pf-t--global--spacer--sm);
322
+ align-self: stretch;
323
+ }
324
+
311
325
  .pf-chatbot__footnote {
312
326
  align-self: center;
313
327
  }
@@ -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/Compare/Compare.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/ImageMessage/ImageMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.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/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.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;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AC1GF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAGI;AAAA;IACE;IACA;;;ACpBJ;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;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;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;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;ACvLN;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;IACA;;;AASJ;EACE;;;AC5CJ;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;;;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;;;ACvIF;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;;;AAKN;EACE;;;AAGF;EACE;;;AClFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;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;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;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;;;AAMJ;EACE;EACA;EACA;;;AC7FF;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;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AD9CN;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;;;AEhFF;EACE;EACA;EACA;EACA;EAGA;;;ADDE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AE7CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ALjBJ;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;;;;AMjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;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;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;ACxFN;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;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;ADtCN;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;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;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;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC5BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;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/Compare/Compare.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/ImageMessage/ImageMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.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/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.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;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AC1GF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAGI;AAAA;IACE;IACA;;;ACpBJ;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;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;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;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;ACvMF;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;IACA;;;AASJ;EACE;;;AC5CJ;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;;;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;;;ACvIF;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;;;AAKN;EACE;;;AAGF;EACE;;;AClFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;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;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;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;;;AAMJ;EACE;EACA;EACA;;;AC7FF;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;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AD9CN;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;;;AEhFF;EACE;EACA;EACA;EACA;EAGA;;;ADDE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AE7CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ALjBJ;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;;;;AMjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;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;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;ACxFN;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;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;ADtCN;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;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;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;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC5BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
- import { DrawerProps, MenuItemProps, MenuProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps } from '@patternfly/react-core';
2
+ import { DrawerProps, MenuItemProps, MenuProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps } from '@patternfly/react-core';
3
3
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
4
+ import { HistoryEmptyStateProps } from './EmptyState';
4
5
  export interface Conversation {
5
6
  /** Conversation id */
6
7
  id: string;
@@ -69,6 +70,12 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
69
70
  drawerCloseButtonProps?: DrawerCloseButtonProps;
70
71
  /** Additional props appleid to drawer panel body */
71
72
  drawerPanelBodyProps?: DrawerPanelBodyProps;
73
+ /** Whether to show drawer loading state */
74
+ isLoading?: boolean;
75
+ /** Additional props for loading state */
76
+ loadingState?: SkeletonProps;
77
+ /** Content to show in error state. Error state will appear once content is passed in. */
78
+ errorState?: HistoryEmptyStateProps;
72
79
  }
73
80
  export declare const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps>;
74
81
  export default ChatbotConversationHistoryNav;
@@ -18,8 +18,10 @@ import { Button, Drawer, DrawerPanelContent, DrawerContent, DrawerPanelBody, Dra
18
18
  import { OutlinedCommentAltIcon } from '@patternfly/react-icons';
19
19
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
20
20
  import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
21
+ import LoadingState from './LoadingState';
22
+ import HistoryEmptyState from './EmptyState';
21
23
  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, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', menuProps, drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "menuProps", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps"]);
24
+ 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', menuProps, drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, isLoading, loadingState, errorState } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "newChatButtonText", "drawerContent", "onNewChat", "searchInputPlaceholder", "searchInputAriaLabel", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "menuProps", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "isLoading", "loadingState", "errorState"]);
23
25
  const drawerRef = React.useRef(null);
24
26
  const onExpand = () => {
25
27
  drawerRef.current && drawerRef.current.focus();
@@ -46,16 +48,26 @@ export const ChatbotConversationHistoryNav = (_a) => {
46
48
  // Menu Content
47
49
  // - Consumers should pass an array to <Chatbot> of the list of conversations
48
50
  // - Groups could be optional, but items need to be ordered by date
49
- const menuContent = (React.createElement(Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps),
50
- React.createElement(MenuContent, null, buildMenu())));
51
- const panelContent = (React.createElement(DrawerPanelContent, Object.assign({ focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps),
52
- React.createElement(DrawerHead, Object.assign({}, drawerHeadProps),
53
- React.createElement(DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps),
54
- React.createElement(DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)),
55
- onNewChat && React.createElement(Button, { onClick: onNewChat }, newChatButtonText))),
51
+ const renderMenuContent = () => {
52
+ if (errorState) {
53
+ return React.createElement(HistoryEmptyState, Object.assign({}, errorState));
54
+ }
55
+ return (React.createElement(Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps),
56
+ React.createElement(MenuContent, null, buildMenu())));
57
+ };
58
+ const renderDrawerContent = () => (React.createElement(React.Fragment, null,
56
59
  handleTextInputChange && (React.createElement("div", { className: "pf-chatbot__input" },
57
60
  React.createElement(SearchInput, { "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }))),
58
- React.createElement(DrawerPanelBody, Object.assign({}, drawerPanelBodyProps), menuContent)));
61
+ React.createElement(DrawerPanelBody, Object.assign({}, drawerPanelBodyProps), renderMenuContent())));
62
+ const renderPanelContent = () => {
63
+ const drawer = (React.createElement(React.Fragment, null,
64
+ React.createElement(DrawerHead, Object.assign({}, drawerHeadProps),
65
+ React.createElement(DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps),
66
+ React.createElement(DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)),
67
+ onNewChat && React.createElement(Button, { onClick: onNewChat }, newChatButtonText))),
68
+ isLoading ? React.createElement(LoadingState, Object.assign({}, loadingState)) : renderDrawerContent()));
69
+ return (React.createElement(DrawerPanelContent, Object.assign({ "aria-live": "polite", focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps), drawer));
70
+ };
59
71
  // An onKeyDown property must be passed to the Drawer component to handle closing
60
72
  // the drawer panel and deactivating the focus trap via the Escape key.
61
73
  const onEscape = (event) => {
@@ -67,7 +79,7 @@ export const ChatbotConversationHistoryNav = (_a) => {
67
79
  }
68
80
  };
69
81
  return (React.createElement(Drawer, Object.assign({ className: "pf-chatbot__history", isExpanded: isDrawerOpen, onExpand: onExpand, position: "start", onKeyDown: onEscape, isInline: displayMode === ChatbotDisplayMode.fullscreen || displayMode === ChatbotDisplayMode.embedded }, props),
70
- React.createElement(DrawerContent, Object.assign({ panelContent: panelContent }, drawerContentProps),
82
+ React.createElement(DrawerContent, Object.assign({ panelContent: renderPanelContent() }, drawerContentProps),
71
83
  React.createElement(DrawerContentBody, Object.assign({}, drawerContentBodyProps),
72
84
  React.createElement(React.Fragment, null,
73
85
  React.createElement("div", { className: `${isDrawerOpen && (displayMode === ChatbotDisplayMode.default || displayMode === ChatbotDisplayMode.docked) ? 'pf-v6-c-backdrop pf-chatbot__drawer-backdrop' : undefined} ` }),
@@ -12,6 +12,33 @@ import '@testing-library/jest-dom';
12
12
  import { fireEvent, render, screen, waitFor } from '@testing-library/react';
13
13
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
14
14
  import ChatbotConversationHistoryNav from './ChatbotConversationHistoryNav';
15
+ import { EmptyStateStatus, Spinner } from '@patternfly/react-core';
16
+ const ERROR = {
17
+ bodyText: (React.createElement(React.Fragment, null,
18
+ "To try again, check your connection and reload this page. If the issue persists,",
19
+ ' ',
20
+ React.createElement("a", { href: "" }, "contact the support team"),
21
+ ".")),
22
+ buttonText: 'Reload',
23
+ buttonIcon: React.createElement(Spinner, { size: "sm" }),
24
+ hasButton: true,
25
+ titleText: 'Could not load chat history',
26
+ status: EmptyStateStatus.danger,
27
+ onClick: () => alert('Clicked Reload')
28
+ };
29
+ const ERROR_WITHOUT_BUTTON = {
30
+ bodyText: (React.createElement(React.Fragment, null,
31
+ "To try again, check your connection and reload this page. If the issue persists,",
32
+ ' ',
33
+ React.createElement("a", { href: "" }, "contact the support team"),
34
+ ".")),
35
+ buttonText: 'Reload',
36
+ buttonIcon: React.createElement(Spinner, { size: "sm" }),
37
+ hasButton: false,
38
+ titleText: 'Could not load chat history',
39
+ status: EmptyStateStatus.danger,
40
+ onClick: () => alert('Clicked Reload')
41
+ };
15
42
  describe('ChatbotConversationHistoryNav', () => {
16
43
  const onDrawerToggle = jest.fn();
17
44
  const initialConversations = [
@@ -97,4 +124,37 @@ describe('ChatbotConversationHistoryNav', () => {
97
124
  const element = container.querySelector('.test');
98
125
  expect(element).toBeInTheDocument();
99
126
  });
127
+ it('should show loading state if triggered', () => {
128
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, isLoading: true }));
129
+ expect(screen.getByRole('dialog', { name: /Loading chatbot conversation history/i })).toBeTruthy();
130
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
131
+ });
132
+ it('should pass alternative aria label to loading state', () => {
133
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, isLoading: true, loadingState: { screenreaderText: 'I am a test' } }));
134
+ expect(screen.getByRole('dialog', { name: /I am a test/i })).toBeTruthy();
135
+ });
136
+ it('should accept errorState', () => {
137
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, errorState: ERROR }));
138
+ expect(screen.getByRole('dialog', {
139
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team . Loading... Reload/i
140
+ })).toBeTruthy();
141
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
142
+ expect(screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
143
+ expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
144
+ expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
145
+ });
146
+ it('should accept errorState without button', () => {
147
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, errorState: ERROR_WITHOUT_BUTTON }));
148
+ expect(screen.getByRole('dialog', {
149
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team ./i
150
+ })).toBeTruthy();
151
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
152
+ expect(screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
153
+ expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
154
+ expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
155
+ });
156
+ it('should show loading state over error state if both are supplied', () => {
157
+ render(React.createElement(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: jest.fn(), conversations: initialConversations, isLoading: true, errorState: ERROR }));
158
+ expect(screen.getByRole('dialog', { name: /Loading/i })).toBeTruthy();
159
+ });
100
160
  });
@@ -0,0 +1,11 @@
1
+ import { EmptyStateProps } from '@patternfly/react-core';
2
+ import React from 'react';
3
+ export interface HistoryEmptyStateProps extends EmptyStateProps {
4
+ onClick?: () => void;
5
+ bodyText?: string | React.ReactNode;
6
+ buttonText?: string;
7
+ buttonIcon?: React.ReactNode;
8
+ hasButton?: boolean;
9
+ }
10
+ export declare const HistoryEmptyState: React.FunctionComponent<HistoryEmptyStateProps>;
11
+ export default HistoryEmptyState;
@@ -0,0 +1,22 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core';
13
+ import React from 'react';
14
+ export const HistoryEmptyState = (_a) => {
15
+ var { bodyText, buttonIcon, buttonText, status, titleText, headingLevel, onClick, hasButton = false } = _a, props = __rest(_a, ["bodyText", "buttonIcon", "buttonText", "status", "titleText", "headingLevel", "onClick", "hasButton"]);
16
+ return (React.createElement(EmptyState, Object.assign({ status: status, titleText: titleText, headingLevel: headingLevel }, props),
17
+ React.createElement(EmptyStateBody, null, bodyText),
18
+ hasButton && (React.createElement(EmptyStateFooter, null,
19
+ React.createElement(EmptyStateActions, null,
20
+ React.createElement(Button, { icon: buttonIcon, variant: "secondary", onClick: onClick }, buttonText))))));
21
+ };
22
+ export default HistoryEmptyState;
@@ -0,0 +1,4 @@
1
+ import { SkeletonProps } from '@patternfly/react-core';
2
+ import React from 'react';
3
+ export declare const LoadingState: React.FunctionComponent<SkeletonProps>;
4
+ export default LoadingState;
@@ -0,0 +1,38 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { Skeleton } from '@patternfly/react-core';
13
+ import React from 'react';
14
+ export const LoadingState = (_a) => {
15
+ var { screenreaderText } = _a, rest = __rest(_a, ["screenreaderText"]);
16
+ return (React.createElement("div", { className: "pf-chatbot__history-loading" },
17
+ React.createElement("div", { className: "pf-chatbot__history-loading-block" },
18
+ React.createElement(Skeleton, Object.assign({ screenreaderText: screenreaderText !== null && screenreaderText !== void 0 ? screenreaderText : 'Loading chatbot conversation history', fontSize: "3xl" }, rest))),
19
+ React.createElement("div", { className: "pf-chatbot__history-loading-block" },
20
+ React.createElement(Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
21
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
22
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
23
+ React.createElement("div", { className: "pf-chatbot__history-loading-block" },
24
+ React.createElement(Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
25
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
26
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
27
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
28
+ React.createElement("div", { className: "pf-chatbot__history-loading-block" },
29
+ React.createElement(Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
30
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
31
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
32
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)),
33
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest))),
34
+ React.createElement("div", { className: "pf-chatbot__history-loading-block" },
35
+ React.createElement(Skeleton, Object.assign({ fontSize: "sm", width: "70%" }, rest)),
36
+ React.createElement(Skeleton, Object.assign({ fontSize: "3xl" }, rest)))));
37
+ };
38
+ export default LoadingState;
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../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.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.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/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/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/ImageMessage/ImageMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.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.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/__mocks__/rehype-unwrap-images.tsx"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../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/EmptyState.tsx","../src/ChatbotConversationHistoryNav/LoadingState.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.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/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/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/ImageMessage/ImageMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.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.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/__mocks__/rehype-unwrap-images.tsx"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.2.0-prerelease.26",
3
+ "version": "2.2.0-prerelease.27",
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",
@@ -3,7 +3,7 @@ import { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot';
3
3
  import ChatbotConversationHistoryNav, {
4
4
  Conversation
5
5
  } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
6
- import { Checkbox } from '@patternfly/react-core';
6
+ import { Checkbox, EmptyStateStatus, Spinner } from '@patternfly/react-core';
7
7
 
8
8
  const initialConversations: { [key: string]: Conversation[] } = {
9
9
  Today: [{ id: '1', text: 'Red Hat products and services' }],
@@ -31,12 +31,29 @@ const initialConversations: { [key: string]: Conversation[] } = {
31
31
  ]
32
32
  };
33
33
 
34
+ const ERROR = {
35
+ bodyText: (
36
+ <>
37
+ To try again, check your connection and reload this page. If the issue persists,{' '}
38
+ <a href="">contact the support team</a>.
39
+ </>
40
+ ),
41
+ buttonText: 'Reload',
42
+ buttonIcon: <Spinner size="sm" />,
43
+ hasButton: true,
44
+ titleText: 'Could not load chat history',
45
+ status: EmptyStateStatus.danger,
46
+ onClick: () => alert('Clicked Reload')
47
+ };
48
+
34
49
  export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
35
50
  const [isOpen, setIsOpen] = React.useState(true);
36
51
  const [isButtonOrderReversed, setIsButtonOrderReversed] = React.useState(false);
37
52
  const [conversations, setConversations] = React.useState<Conversation[] | { [key: string]: Conversation[] }>(
38
53
  initialConversations
39
54
  );
55
+ const [isLoading, setIsLoading] = React.useState(false);
56
+ const [hasError, setHasError] = React.useState(false);
40
57
  const displayMode = ChatbotDisplayMode.embedded;
41
58
 
42
59
  const findMatchingItems = (targetValue: string) => {
@@ -74,6 +91,20 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
74
91
  id="drawer-actions-visible"
75
92
  name="drawer-actions-visible"
76
93
  ></Checkbox>
94
+ <Checkbox
95
+ label="Show loading state"
96
+ isChecked={isLoading}
97
+ onChange={() => setIsLoading(!isLoading)}
98
+ id="drawer-is-loading"
99
+ name="drawer-is-loading"
100
+ ></Checkbox>
101
+ <Checkbox
102
+ label="Show error state"
103
+ isChecked={hasError}
104
+ onChange={() => setHasError(!hasError)}
105
+ id="drawer-has-error"
106
+ name="drawer-has-error"
107
+ ></Checkbox>
77
108
  <ChatbotConversationHistoryNav
78
109
  displayMode={displayMode}
79
110
  onDrawerToggle={() => setIsOpen(!isOpen)}
@@ -96,6 +127,8 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
96
127
  setConversations(newConversations);
97
128
  }}
98
129
  drawerContent={<div>Drawer content</div>}
130
+ isLoading={isLoading}
131
+ errorState={hasError ? ERROR : undefined}
99
132
  />
100
133
  </>
101
134
  );
@@ -189,3 +189,17 @@
189
189
  }
190
190
  }
191
191
  }
192
+
193
+ .pf-chatbot__history-loading {
194
+ display: flex;
195
+ padding: var(--pf-t--global--spacer--lg);
196
+ flex-direction: column;
197
+ gap: var(--pf-t--global--spacer--lg);
198
+ }
199
+
200
+ .pf-chatbot__history-loading-block {
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: var(--pf-t--global--spacer--sm);
204
+ align-self: stretch;
205
+ }
@@ -4,6 +4,37 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
4
4
 
5
5
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
6
6
  import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';
7
+ import { EmptyStateStatus, Spinner } from '@patternfly/react-core';
8
+
9
+ const ERROR = {
10
+ bodyText: (
11
+ <>
12
+ To try again, check your connection and reload this page. If the issue persists,{' '}
13
+ <a href="">contact the support team</a>.
14
+ </>
15
+ ),
16
+ buttonText: 'Reload',
17
+ buttonIcon: <Spinner size="sm" />,
18
+ hasButton: true,
19
+ titleText: 'Could not load chat history',
20
+ status: EmptyStateStatus.danger,
21
+ onClick: () => alert('Clicked Reload')
22
+ };
23
+
24
+ const ERROR_WITHOUT_BUTTON = {
25
+ bodyText: (
26
+ <>
27
+ To try again, check your connection and reload this page. If the issue persists,{' '}
28
+ <a href="">contact the support team</a>.
29
+ </>
30
+ ),
31
+ buttonText: 'Reload',
32
+ buttonIcon: <Spinner size="sm" />,
33
+ hasButton: false,
34
+ titleText: 'Could not load chat history',
35
+ status: EmptyStateStatus.danger,
36
+ onClick: () => alert('Clicked Reload')
37
+ };
7
38
 
8
39
  describe('ChatbotConversationHistoryNav', () => {
9
40
  const onDrawerToggle = jest.fn();
@@ -232,4 +263,103 @@ describe('ChatbotConversationHistoryNav', () => {
232
263
  const element = container.querySelector('.test');
233
264
  expect(element).toBeInTheDocument();
234
265
  });
266
+
267
+ it('should show loading state if triggered', () => {
268
+ render(
269
+ <ChatbotConversationHistoryNav
270
+ onDrawerToggle={onDrawerToggle}
271
+ isDrawerOpen={true}
272
+ displayMode={ChatbotDisplayMode.fullscreen}
273
+ setIsDrawerOpen={jest.fn()}
274
+ reverseButtonOrder={false}
275
+ handleTextInputChange={jest.fn()}
276
+ conversations={initialConversations}
277
+ isLoading
278
+ />
279
+ );
280
+ expect(screen.getByRole('dialog', { name: /Loading chatbot conversation history/i })).toBeTruthy();
281
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
282
+ });
283
+
284
+ it('should pass alternative aria label to loading state', () => {
285
+ render(
286
+ <ChatbotConversationHistoryNav
287
+ onDrawerToggle={onDrawerToggle}
288
+ isDrawerOpen={true}
289
+ displayMode={ChatbotDisplayMode.fullscreen}
290
+ setIsDrawerOpen={jest.fn()}
291
+ reverseButtonOrder={false}
292
+ handleTextInputChange={jest.fn()}
293
+ conversations={initialConversations}
294
+ isLoading
295
+ loadingState={{ screenreaderText: 'I am a test' }}
296
+ />
297
+ );
298
+ expect(screen.getByRole('dialog', { name: /I am a test/i })).toBeTruthy();
299
+ });
300
+
301
+ it('should accept errorState', () => {
302
+ render(
303
+ <ChatbotConversationHistoryNav
304
+ onDrawerToggle={onDrawerToggle}
305
+ isDrawerOpen={true}
306
+ displayMode={ChatbotDisplayMode.fullscreen}
307
+ setIsDrawerOpen={jest.fn()}
308
+ reverseButtonOrder={false}
309
+ handleTextInputChange={jest.fn()}
310
+ conversations={initialConversations}
311
+ errorState={ERROR}
312
+ />
313
+ );
314
+ expect(
315
+ screen.getByRole('dialog', {
316
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team . Loading... Reload/i
317
+ })
318
+ ).toBeTruthy();
319
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
320
+ expect(screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
321
+ expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
322
+ expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
323
+ });
324
+
325
+ it('should accept errorState without button', () => {
326
+ render(
327
+ <ChatbotConversationHistoryNav
328
+ onDrawerToggle={onDrawerToggle}
329
+ isDrawerOpen={true}
330
+ displayMode={ChatbotDisplayMode.fullscreen}
331
+ setIsDrawerOpen={jest.fn()}
332
+ reverseButtonOrder={false}
333
+ handleTextInputChange={jest.fn()}
334
+ conversations={initialConversations}
335
+ errorState={ERROR_WITHOUT_BUTTON}
336
+ />
337
+ );
338
+ expect(
339
+ screen.getByRole('dialog', {
340
+ name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team ./i
341
+ })
342
+ ).toBeTruthy();
343
+ expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
344
+ expect(screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
345
+ expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
346
+ expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
347
+ });
348
+
349
+ it('should show loading state over error state if both are supplied', () => {
350
+ render(
351
+ <ChatbotConversationHistoryNav
352
+ onDrawerToggle={onDrawerToggle}
353
+ isDrawerOpen={true}
354
+ displayMode={ChatbotDisplayMode.fullscreen}
355
+ setIsDrawerOpen={jest.fn()}
356
+ reverseButtonOrder={false}
357
+ handleTextInputChange={jest.fn()}
358
+ conversations={initialConversations}
359
+ isLoading
360
+ errorState={ERROR}
361
+ />
362
+ );
363
+ expect(screen.getByRole('dialog', { name: /Loading/i })).toBeTruthy();
364
+ });
235
365
  });
@@ -29,12 +29,15 @@ import {
29
29
  DrawerHeadProps,
30
30
  DrawerActionsProps,
31
31
  DrawerCloseButtonProps,
32
- DrawerPanelBodyProps
32
+ DrawerPanelBodyProps,
33
+ SkeletonProps
33
34
  } from '@patternfly/react-core';
34
35
 
35
36
  import { OutlinedCommentAltIcon } from '@patternfly/react-icons';
36
37
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
37
38
  import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
39
+ import LoadingState from './LoadingState';
40
+ import HistoryEmptyState, { HistoryEmptyStateProps } from './EmptyState';
38
41
 
39
42
  export interface Conversation {
40
43
  /** Conversation id */
@@ -103,6 +106,12 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
103
106
  drawerCloseButtonProps?: DrawerCloseButtonProps;
104
107
  /** Additional props appleid to drawer panel body */
105
108
  drawerPanelBodyProps?: DrawerPanelBodyProps;
109
+ /** Whether to show drawer loading state */
110
+ isLoading?: boolean;
111
+ /** Additional props for loading state */
112
+ loadingState?: SkeletonProps;
113
+ /** Content to show in error state. Error state will appear once content is passed in. */
114
+ errorState?: HistoryEmptyStateProps;
106
115
  }
107
116
 
108
117
  export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps> = ({
@@ -129,6 +138,9 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
129
138
  drawerActionsProps,
130
139
  drawerCloseButtonProps,
131
140
  drawerPanelBodyProps,
141
+ isLoading,
142
+ loadingState,
143
+ errorState,
132
144
  ...props
133
145
  }: ChatbotConversationHistoryNavProps) => {
134
146
  const drawerRef = React.useRef<HTMLDivElement>(null);
@@ -194,24 +206,19 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
194
206
  // Menu Content
195
207
  // - Consumers should pass an array to <Chatbot> of the list of conversations
196
208
  // - Groups could be optional, but items need to be ordered by date
197
- const menuContent = (
198
- <Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
199
- <MenuContent>{buildMenu()}</MenuContent>
200
- </Menu>
201
- );
209
+ const renderMenuContent = () => {
210
+ if (errorState) {
211
+ return <HistoryEmptyState {...errorState} />;
212
+ }
213
+ return (
214
+ <Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
215
+ <MenuContent>{buildMenu()}</MenuContent>
216
+ </Menu>
217
+ );
218
+ };
202
219
 
203
- const panelContent = (
204
- <DrawerPanelContent focusTrap={{ enabled: true }} defaultSize="384px" {...drawerPanelContentProps}>
205
- <DrawerHead {...drawerHeadProps}>
206
- <DrawerActions
207
- data-testid={drawerActionsTestId}
208
- className={reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : ''}
209
- {...drawerActionsProps}
210
- >
211
- <DrawerCloseButton onClick={onDrawerToggle} {...drawerCloseButtonProps} />
212
- {onNewChat && <Button onClick={onNewChat}>{newChatButtonText}</Button>}
213
- </DrawerActions>
214
- </DrawerHead>
220
+ const renderDrawerContent = () => (
221
+ <>
215
222
  {handleTextInputChange && (
216
223
  <div className="pf-chatbot__input">
217
224
  <SearchInput
@@ -221,10 +228,38 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
221
228
  />
222
229
  </div>
223
230
  )}
224
- <DrawerPanelBody {...drawerPanelBodyProps}>{menuContent}</DrawerPanelBody>
225
- </DrawerPanelContent>
231
+ <DrawerPanelBody {...drawerPanelBodyProps}>{renderMenuContent()}</DrawerPanelBody>
232
+ </>
226
233
  );
227
234
 
235
+ const renderPanelContent = () => {
236
+ const drawer = (
237
+ <>
238
+ <DrawerHead {...drawerHeadProps}>
239
+ <DrawerActions
240
+ data-testid={drawerActionsTestId}
241
+ className={reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : ''}
242
+ {...drawerActionsProps}
243
+ >
244
+ <DrawerCloseButton onClick={onDrawerToggle} {...drawerCloseButtonProps} />
245
+ {onNewChat && <Button onClick={onNewChat}>{newChatButtonText}</Button>}
246
+ </DrawerActions>
247
+ </DrawerHead>
248
+ {isLoading ? <LoadingState {...loadingState} /> : renderDrawerContent()}
249
+ </>
250
+ );
251
+ return (
252
+ <DrawerPanelContent
253
+ aria-live="polite"
254
+ focusTrap={{ enabled: true }}
255
+ defaultSize="384px"
256
+ {...drawerPanelContentProps}
257
+ >
258
+ {drawer}
259
+ </DrawerPanelContent>
260
+ );
261
+ };
262
+
228
263
  // An onKeyDown property must be passed to the Drawer component to handle closing
229
264
  // the drawer panel and deactivating the focus trap via the Escape key.
230
265
  const onEscape = (event: React.KeyboardEvent) => {
@@ -246,7 +281,7 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
246
281
  isInline={displayMode === ChatbotDisplayMode.fullscreen || displayMode === ChatbotDisplayMode.embedded}
247
282
  {...props}
248
283
  >
249
- <DrawerContent panelContent={panelContent} {...drawerContentProps}>
284
+ <DrawerContent panelContent={renderPanelContent()} {...drawerContentProps}>
250
285
  <DrawerContentBody {...drawerContentBodyProps}>
251
286
  <>
252
287
  <div
@@ -0,0 +1,44 @@
1
+ import {
2
+ Button,
3
+ EmptyState,
4
+ EmptyStateActions,
5
+ EmptyStateBody,
6
+ EmptyStateFooter,
7
+ EmptyStateProps
8
+ } from '@patternfly/react-core';
9
+ import React from 'react';
10
+
11
+ export interface HistoryEmptyStateProps extends EmptyStateProps {
12
+ onClick?: () => void;
13
+ bodyText?: string | React.ReactNode;
14
+ buttonText?: string;
15
+ buttonIcon?: React.ReactNode;
16
+ hasButton?: boolean;
17
+ }
18
+
19
+ export const HistoryEmptyState: React.FunctionComponent<HistoryEmptyStateProps> = ({
20
+ bodyText,
21
+ buttonIcon,
22
+ buttonText,
23
+ status,
24
+ titleText,
25
+ headingLevel,
26
+ onClick,
27
+ hasButton = false,
28
+ ...props
29
+ }: HistoryEmptyStateProps) => (
30
+ <EmptyState status={status} titleText={titleText} headingLevel={headingLevel} {...props}>
31
+ <EmptyStateBody>{bodyText}</EmptyStateBody>
32
+ {hasButton && (
33
+ <EmptyStateFooter>
34
+ <EmptyStateActions>
35
+ <Button icon={buttonIcon} variant="secondary" onClick={onClick}>
36
+ {buttonText}
37
+ </Button>
38
+ </EmptyStateActions>
39
+ </EmptyStateFooter>
40
+ )}
41
+ </EmptyState>
42
+ );
43
+
44
+ export default HistoryEmptyState;
@@ -0,0 +1,38 @@
1
+ import { Skeleton, SkeletonProps } from '@patternfly/react-core';
2
+ import React from 'react';
3
+
4
+ export const LoadingState: React.FunctionComponent<SkeletonProps> = ({ screenreaderText, ...rest }: SkeletonProps) => (
5
+ <div className="pf-chatbot__history-loading">
6
+ <div className="pf-chatbot__history-loading-block">
7
+ <Skeleton
8
+ screenreaderText={screenreaderText ?? 'Loading chatbot conversation history'}
9
+ fontSize="3xl"
10
+ {...rest}
11
+ />
12
+ </div>
13
+ <div className="pf-chatbot__history-loading-block">
14
+ <Skeleton fontSize="sm" width="70%" {...rest} />
15
+ <Skeleton fontSize="3xl" {...rest} />
16
+ <Skeleton fontSize="3xl" {...rest} />
17
+ </div>
18
+ <div className="pf-chatbot__history-loading-block">
19
+ <Skeleton fontSize="sm" width="70%" {...rest} />
20
+ <Skeleton fontSize="3xl" {...rest} />
21
+ <Skeleton fontSize="3xl" {...rest} />
22
+ <Skeleton fontSize="3xl" {...rest} />
23
+ </div>
24
+ <div className="pf-chatbot__history-loading-block">
25
+ <Skeleton fontSize="sm" width="70%" {...rest} />
26
+ <Skeleton fontSize="3xl" {...rest} />
27
+ <Skeleton fontSize="3xl" {...rest} />
28
+ <Skeleton fontSize="3xl" {...rest} />
29
+ <Skeleton fontSize="3xl" {...rest} />
30
+ </div>
31
+ <div className="pf-chatbot__history-loading-block">
32
+ <Skeleton fontSize="sm" width="70%" {...rest} />
33
+ <Skeleton fontSize="3xl" {...rest} />
34
+ </div>
35
+ </div>
36
+ );
37
+
38
+ export default LoadingState;