@patternfly/chatbot 6.5.0-prerelease.2 → 6.5.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.
- package/dist/cjs/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/cjs/AttachMenu/AttachMenu.js +2 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
- package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
- package/dist/cjs/CodeModal/CodeModal.js +53 -8
- package/dist/cjs/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
- package/dist/cjs/Message/Message.d.ts +21 -3
- package/dist/cjs/Message/Message.js +11 -8
- package/dist/cjs/Message/Message.test.js +161 -2
- package/dist/cjs/Message/MessageLoading.d.ts +2 -1
- package/dist/cjs/Message/MessageLoading.js +1 -1
- package/dist/cjs/Message/TableMessage/TableMessage.d.ts +4 -1
- package/dist/cjs/Message/TableMessage/TableMessage.js +2 -2
- package/dist/cjs/Message/TextMessage/TextMessage.d.ts +4 -1
- package/dist/cjs/Message/TextMessage/TextMessage.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.d.ts +2 -0
- package/dist/cjs/MessageBar/AttachButton.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.test.js +4 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +16 -6
- package/dist/cjs/MessageBar/MessageBar.js +6 -5
- package/dist/cjs/MessageBar/MessageBar.test.js +62 -0
- package/dist/cjs/Onboarding/Onboarding.d.ts +36 -0
- package/dist/cjs/Onboarding/Onboarding.js +37 -0
- package/dist/cjs/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/cjs/Onboarding/Onboarding.test.js +80 -0
- package/dist/cjs/Onboarding/index.d.ts +2 -0
- package/dist/cjs/Onboarding/index.js +23 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +3 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +28 -7
- package/dist/cjs/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/cjs/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/cjs/__mocks__/monaco-editor.js +18 -0
- package/dist/cjs/__mocks__/rehype-highlight.d.ts +2 -0
- package/dist/cjs/__mocks__/rehype-highlight.js +4 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/css/main.css +229 -21
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/Onboarding/package.json +1 -0
- package/dist/esm/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/esm/AttachMenu/AttachMenu.js +2 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
- package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
- package/dist/esm/CodeModal/CodeModal.js +54 -9
- package/dist/esm/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
- package/dist/esm/Message/Message.d.ts +21 -3
- package/dist/esm/Message/Message.js +11 -8
- package/dist/esm/Message/Message.test.js +161 -2
- package/dist/esm/Message/MessageLoading.d.ts +2 -1
- package/dist/esm/Message/MessageLoading.js +1 -1
- package/dist/esm/Message/TableMessage/TableMessage.d.ts +4 -1
- package/dist/esm/Message/TableMessage/TableMessage.js +2 -2
- package/dist/esm/Message/TextMessage/TextMessage.d.ts +4 -1
- package/dist/esm/Message/TextMessage/TextMessage.js +2 -2
- package/dist/esm/MessageBar/AttachButton.d.ts +2 -0
- package/dist/esm/MessageBar/AttachButton.js +2 -2
- package/dist/esm/MessageBar/AttachButton.test.js +4 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +16 -6
- package/dist/esm/MessageBar/MessageBar.js +6 -5
- package/dist/esm/MessageBar/MessageBar.test.js +62 -0
- package/dist/esm/Onboarding/Onboarding.d.ts +36 -0
- package/dist/esm/Onboarding/Onboarding.js +30 -0
- package/dist/esm/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/esm/Onboarding/Onboarding.test.js +75 -0
- package/dist/esm/Onboarding/index.d.ts +2 -0
- package/dist/esm/Onboarding/index.js +2 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +3 -0
- package/dist/esm/ResponseActions/ResponseActions.js +28 -7
- package/dist/esm/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/esm/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/esm/__mocks__/monaco-editor.js +18 -0
- package/dist/esm/__mocks__/rehype-highlight.d.ts +2 -0
- package/dist/esm/__mocks__/rehype-highlight.js +2 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -2
- package/patternfly-docs/content/extensions/chatbot/chatbot.md +57 -0
- package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +12 -12
- package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Customizing Messages/Customizing Messages.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMultipleActionGroups.tsx +61 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithPersistedActions.tsx +22 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +36 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +3 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarIndicatorThinking.tsx +15 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactOnboarding.tsx +141 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Onboarding.tsx +151 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/RH-Hat-Image.svg +9 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +55 -27
- package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +18 -18
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +29 -21
- package/patternfly-docs/content/extensions/chatbot/examples/demos/WhiteEmbeddedChatbot.tsx +451 -0
- package/patternfly-docs/patternfly-docs.config.js +2 -1
- package/patternfly-docs/patternfly-docs.source.js +1 -1
- package/src/AttachMenu/AttachMenu.tsx +26 -11
- package/src/Chatbot/Chatbot.scss +23 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +25 -0
- package/src/ChatbotFooter/ChatbotFooter.scss +21 -0
- package/src/ChatbotFooter/ChatbotFooter.test.tsx +10 -1
- package/src/ChatbotFooter/ChatbotFooter.tsx +10 -3
- package/src/ChatbotHeader/ChatbotHeader.scss +19 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
- package/src/ChatbotModal/ChatbotModal.scss +3 -0
- package/src/CodeModal/CodeModal.tsx +72 -23
- package/src/DeepThinking/DeepThinking.scss +1 -1
- package/src/FileDetailsLabel/FileDetailsLabel.tsx +2 -2
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +12 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +4 -1
- package/src/Message/Message.scss +11 -7
- package/src/Message/Message.test.tsx +239 -2
- package/src/Message/Message.tsx +61 -17
- package/src/Message/MessageLoading.scss +7 -0
- package/src/Message/MessageLoading.tsx +2 -2
- package/src/Message/TableMessage/TableMessage.scss +6 -1
- package/src/Message/TableMessage/TableMessage.tsx +6 -2
- package/src/Message/TextMessage/TextMessage.scss +10 -0
- package/src/Message/TextMessage/TextMessage.tsx +11 -2
- package/src/Message/UserFeedback/UserFeedback.scss +2 -1
- package/src/MessageBar/AttachButton.test.tsx +4 -0
- package/src/MessageBar/AttachButton.tsx +4 -1
- package/src/MessageBar/MessageBar.scss +40 -3
- package/src/MessageBar/MessageBar.test.tsx +102 -1
- package/src/MessageBar/MessageBar.tsx +44 -11
- package/src/Onboarding/Onboarding.scss +101 -0
- package/src/Onboarding/Onboarding.test.tsx +148 -0
- package/src/Onboarding/Onboarding.tsx +126 -0
- package/src/Onboarding/index.ts +3 -0
- package/src/ResponseActions/ResponseActions.scss +12 -1
- package/src/ResponseActions/ResponseActions.test.tsx +111 -12
- package/src/ResponseActions/ResponseActions.tsx +38 -10
- package/src/ToolCall/ToolCall.scss +1 -1
- package/src/ToolResponse/ToolResponse.scss +3 -3
- package/src/__mocks__/monaco-editor.ts +19 -0
- package/src/__mocks__/rehype-highlight.ts +3 -0
- package/src/index.ts +3 -0
- package/src/main.scss +1 -0
- package/tsconfig.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +0 -44
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'react';
|
|
2
|
-
import { DropdownProps, DropdownToggleProps, PopperOptions } from '@patternfly/react-core';
|
|
2
|
+
import { DropdownProps, DropdownToggleProps, PopperOptions, MenuSearchInputProps, SearchInputProps, MenuSearchProps } from '@patternfly/react-core';
|
|
3
3
|
export interface AttachMenuProps extends DropdownProps {
|
|
4
4
|
/** Items in menu */
|
|
5
5
|
filteredItems: React.ReactNode;
|
|
6
6
|
/** A callback for when the input value changes. */
|
|
7
|
-
handleTextInputChange
|
|
7
|
+
handleTextInputChange?: (value: string) => void;
|
|
8
8
|
/** Flag to indicate if menu is opened. */
|
|
9
9
|
isOpen: boolean;
|
|
10
10
|
/** Additional properties to pass to the Popper */
|
|
@@ -21,6 +21,12 @@ export interface AttachMenuProps extends DropdownProps {
|
|
|
21
21
|
searchInputAriaLabel?: string;
|
|
22
22
|
/** Toggle to be rendered */
|
|
23
23
|
toggle: DropdownToggleProps | ((toggleRef: React.RefObject<any>) => React.ReactNode);
|
|
24
|
+
/** Additional props passed to MenuSearch component */
|
|
25
|
+
menuSearchProps?: Omit<MenuSearchProps, 'ref'>;
|
|
26
|
+
/** Additional props passed to MenuSearchInput component */
|
|
27
|
+
menuSearchInputProps?: Omit<MenuSearchInputProps, 'ref'>;
|
|
28
|
+
/** Additional props passed to SearchInput component */
|
|
29
|
+
searchInputProps?: SearchInputProps;
|
|
24
30
|
}
|
|
25
31
|
export declare const AttachMenu: FunctionComponent<AttachMenuProps>;
|
|
26
32
|
export default AttachMenu;
|
|
@@ -16,8 +16,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
16
16
|
// Import PatternFly components
|
|
17
17
|
const react_core_1 = require("@patternfly/react-core");
|
|
18
18
|
const AttachMenu = (_a) => {
|
|
19
|
-
var { className, filteredItems, handleTextInputChange, isOpen, popperProps = undefined, onOpenChange, onOpenChangeKeys, onSelect, searchInputPlaceholder, searchInputAriaLabel = 'Filter menu items', toggle } = _a, props = __rest(_a, ["className", "filteredItems", "handleTextInputChange", "isOpen", "popperProps", "onOpenChange", "onOpenChangeKeys", "onSelect", "searchInputPlaceholder", "searchInputAriaLabel", "toggle"]);
|
|
20
|
-
return ((0, jsx_runtime_1.jsxs)(react_core_1.Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.MenuSearch, { children: (0, jsx_runtime_1.jsx)(react_core_1.MenuSearchInput, { children: (0, jsx_runtime_1.jsx)(react_core_1.SearchInput, { "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }) }) }), filteredItems] })));
|
|
19
|
+
var { className, filteredItems, handleTextInputChange, isOpen, popperProps = undefined, onOpenChange, onOpenChangeKeys, onSelect, searchInputPlaceholder, searchInputAriaLabel = 'Filter menu items', toggle, menuSearchProps, menuSearchInputProps, searchInputProps } = _a, props = __rest(_a, ["className", "filteredItems", "handleTextInputChange", "isOpen", "popperProps", "onOpenChange", "onOpenChangeKeys", "onSelect", "searchInputPlaceholder", "searchInputAriaLabel", "toggle", "menuSearchProps", "menuSearchInputProps", "searchInputProps"]);
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)(react_core_1.Dropdown, Object.assign({ className: `pf-chatbot__menu ${className !== null && className !== void 0 ? className : ''}`, isOpen: isOpen, onOpenChange: (isOpen) => onOpenChange(isOpen), onOpenChangeKeys: onOpenChangeKeys !== null && onOpenChangeKeys !== void 0 ? onOpenChangeKeys : ['Esc'], toggle: toggle, popperProps: popperProps, onSelect: onSelect }, props, { children: [handleTextInputChange && ((0, jsx_runtime_1.jsx)(react_core_1.MenuSearch, Object.assign({}, menuSearchProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.MenuSearchInput, Object.assign({}, menuSearchInputProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)) })) }))), filteredItems] })));
|
|
21
21
|
};
|
|
22
22
|
exports.AttachMenu = AttachMenu;
|
|
23
23
|
exports.default = exports.AttachMenu;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { HTMLProps, FunctionComponent } from 'react';
|
|
2
2
|
export interface ChatbotFooterProps extends HTMLProps<HTMLDivElement> {
|
|
3
|
-
/** Children for the
|
|
3
|
+
/** Children for the footer - supports MessageBar and FootNote components*/
|
|
4
4
|
children?: React.ReactNode;
|
|
5
|
-
/** Custom classname for the
|
|
5
|
+
/** Custom classname for the footer component */
|
|
6
6
|
className?: string;
|
|
7
|
+
/** Sets footer to compact styling. */
|
|
7
8
|
isCompact?: boolean;
|
|
9
|
+
/** Sets background color to primary */
|
|
10
|
+
isPrimary?: boolean;
|
|
8
11
|
}
|
|
9
12
|
export declare const ChatbotFooter: FunctionComponent<ChatbotFooterProps>;
|
|
10
13
|
export default ChatbotFooter;
|
|
@@ -15,8 +15,8 @@ exports.ChatbotFooter = void 0;
|
|
|
15
15
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
16
|
const react_core_1 = require("@patternfly/react-core");
|
|
17
17
|
const ChatbotFooter = (_a) => {
|
|
18
|
-
var { children, className, isCompact } = _a, props = __rest(_a, ["children", "className", "isCompact"]);
|
|
19
|
-
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `pf-chatbot__footer ${isCompact ? 'pf-m-compact' : ''} ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Divider, {}), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__footer-container", children: children })] })));
|
|
18
|
+
var { children, className, isCompact, isPrimary } = _a, props = __rest(_a, ["children", "className", "isCompact", "isPrimary"]);
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `pf-chatbot__footer ${isCompact ? 'pf-m-compact' : ''} ${isPrimary ? 'pf-m-primary' : ''} ${className !== null && className !== void 0 ? className : ''}` }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Divider, {}), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__footer-container", children: children })] })));
|
|
20
20
|
};
|
|
21
21
|
exports.ChatbotFooter = ChatbotFooter;
|
|
22
22
|
exports.default = exports.ChatbotFooter;
|
|
@@ -17,7 +17,11 @@ describe('ChatbotFooter', () => {
|
|
|
17
17
|
expect(container.querySelector('.custom-class')).toBeTruthy();
|
|
18
18
|
});
|
|
19
19
|
it('should handle isCompact', () => {
|
|
20
|
-
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotFooter_1.default, {
|
|
20
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotFooter_1.default, { isCompact: true, "data-testid": "footer", children: "Chatbot Content" }));
|
|
21
21
|
expect(react_1.screen.getByTestId('footer')).toHaveClass('pf-m-compact');
|
|
22
22
|
});
|
|
23
|
+
it('should handle isPrimary', () => {
|
|
24
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotFooter_1.default, { isPrimary: true, "data-testid": "footer", children: "Chatbot Content" }));
|
|
25
|
+
expect(react_1.screen.getByTestId('footer')).toHaveClass('pf-m-primary');
|
|
26
|
+
});
|
|
23
27
|
});
|
|
@@ -21,8 +21,35 @@ const react_core_1 = require("@patternfly/react-core");
|
|
|
21
21
|
const bars_icon_1 = __importDefault(require("@patternfly/react-icons/dist/esm/icons/bars-icon"));
|
|
22
22
|
const ChatbotHeaderMenuBase = (_a) => {
|
|
23
23
|
var { className, onMenuToggle, tooltipProps, menuAriaLabel = 'Chat history menu', innerRef, tooltipContent = 'Chat history menu', isCompact } = _a, props = __rest(_a, ["className", "onMenuToggle", "tooltipProps", "menuAriaLabel", "innerRef", "tooltipContent", "isCompact"]);
|
|
24
|
-
|
|
24
|
+
const [isDrawerAnimating, setIsDrawerAnimating] = (0, react_1.useState)(false);
|
|
25
|
+
// I'd like to use a prop here later if this works
|
|
26
|
+
const drawerState = props['aria-expanded'];
|
|
27
|
+
const isDrawerOpen = drawerState === true;
|
|
28
|
+
const prevDrawerStateRef = (0, react_1.useRef)(isDrawerOpen);
|
|
29
|
+
const buttonRef = (0, react_1.useRef)(null);
|
|
30
|
+
(0, react_1.useEffect)(() => {
|
|
31
|
+
if (drawerState !== undefined) {
|
|
32
|
+
const wasDrawerOpen = prevDrawerStateRef.current === true;
|
|
33
|
+
const isDrawerClosing = wasDrawerOpen && !isDrawerOpen;
|
|
34
|
+
setIsDrawerAnimating(true);
|
|
35
|
+
const timeout = setTimeout(() => {
|
|
36
|
+
setIsDrawerAnimating(false);
|
|
37
|
+
if (isDrawerClosing) {
|
|
38
|
+
requestAnimationFrame(() => {
|
|
39
|
+
var _a;
|
|
40
|
+
(_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}, 350);
|
|
44
|
+
prevDrawerStateRef.current = isDrawerOpen;
|
|
45
|
+
return () => clearTimeout(timeout);
|
|
46
|
+
}
|
|
47
|
+
}, [drawerState, isDrawerOpen]);
|
|
48
|
+
const button = (0, react_1.useMemo)(() => ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onMenuToggle, "aria-label": menuAriaLabel, ref: innerRef !== null && innerRef !== void 0 ? innerRef : buttonRef, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: (0, jsx_runtime_1.jsx)(bars_icon_1.default, {}) }), size: isCompact ? 'sm' : undefined }, props))),
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
[isCompact, menuAriaLabel, onMenuToggle, innerRef, buttonRef]);
|
|
51
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__menu ${className}`, children: isDrawerAnimating ? (button) : ((0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
|
|
25
52
|
// prevents VO announcements of both aria label and tooltip
|
|
26
|
-
aria: "none" }, tooltipProps, { children:
|
|
53
|
+
aria: "none" }, tooltipProps, { children: button }))) }));
|
|
27
54
|
};
|
|
28
55
|
exports.ChatbotHeaderMenu = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(ChatbotHeaderMenuBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -37,6 +37,8 @@ export interface CodeModalProps {
|
|
|
37
37
|
modalBodyClassName?: string;
|
|
38
38
|
/** Class applied to modal footer */
|
|
39
39
|
modalFooterClassName?: string;
|
|
40
|
+
/** Aria label applied to spinner when loading Monaco */
|
|
41
|
+
spinnerAriaLabel?: string;
|
|
40
42
|
}
|
|
41
43
|
export declare const CodeModal: FunctionComponent<CodeModalProps>;
|
|
42
44
|
export default CodeModal;
|
|
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
25
34
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
35
|
var t = {};
|
|
27
36
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -47,12 +56,39 @@ const react_core_1 = require("@patternfly/react-core");
|
|
|
47
56
|
const FileDetails_1 = __importStar(require("../FileDetails"));
|
|
48
57
|
const Chatbot_1 = require("../Chatbot");
|
|
49
58
|
const ChatbotModal_1 = __importDefault(require("../ChatbotModal/ChatbotModal"));
|
|
59
|
+
// Try to lazy load - some consumers need to be below a certain bundle size, but can't use the CDN and don't have webpack
|
|
60
|
+
let monacoInstance = null;
|
|
61
|
+
const loadMonaco = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
+
if (!monacoInstance) {
|
|
63
|
+
const [monaco, { loader }] = yield Promise.all([Promise.resolve().then(() => __importStar(require('monaco-editor'))), Promise.resolve().then(() => __importStar(require('@monaco-editor/react')))]);
|
|
64
|
+
monacoInstance = monaco;
|
|
65
|
+
loader.config({ monaco });
|
|
66
|
+
}
|
|
67
|
+
return monacoInstance;
|
|
68
|
+
});
|
|
50
69
|
const CodeModal = (_a) => {
|
|
51
|
-
var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = Chatbot_1.ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName"]);
|
|
70
|
+
var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = Chatbot_1.ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName, spinnerAriaLabel = 'Loading' } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName", "spinnerAriaLabel"]);
|
|
52
71
|
const [newCode, setNewCode] = (0, react_1.useState)(code);
|
|
53
72
|
const [editorInstance, setEditorInstance] = (0, react_1.useState)(null);
|
|
54
73
|
const [isEditorReady, setIsEditorReady] = (0, react_1.useState)(false);
|
|
74
|
+
const [isMonacoLoading, setIsMonacoLoading] = (0, react_1.useState)(false);
|
|
75
|
+
const [isMonacoLoaded, setIsMonacoLoaded] = (0, react_1.useState)(false);
|
|
55
76
|
const containerRef = (0, react_1.useRef)(null);
|
|
77
|
+
(0, react_1.useEffect)(() => {
|
|
78
|
+
if (isModalOpen && !isMonacoLoaded && !isMonacoLoading) {
|
|
79
|
+
setIsMonacoLoading(true);
|
|
80
|
+
loadMonaco()
|
|
81
|
+
.then(() => {
|
|
82
|
+
setIsMonacoLoaded(true);
|
|
83
|
+
setIsMonacoLoading(false);
|
|
84
|
+
})
|
|
85
|
+
.catch((error) => {
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.error('Failed to load Monaco editor:', error);
|
|
88
|
+
setIsMonacoLoading(false);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}, [isModalOpen, isMonacoLoaded, isMonacoLoading]);
|
|
56
92
|
(0, react_1.useEffect)(() => {
|
|
57
93
|
if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
|
|
58
94
|
return;
|
|
@@ -102,13 +138,22 @@ const CodeModal = (_a) => {
|
|
|
102
138
|
setNewCode(value);
|
|
103
139
|
}
|
|
104
140
|
};
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
141
|
+
const renderMonacoEditor = () => {
|
|
142
|
+
if (isMonacoLoading) {
|
|
143
|
+
return ((0, jsx_runtime_1.jsx)(react_core_1.Bullseye, { children: (0, jsx_runtime_1.jsx)(react_core_1.Spinner, { "aria-label": spinnerAriaLabel }) }));
|
|
144
|
+
}
|
|
145
|
+
if (isMonacoLoaded) {
|
|
146
|
+
return ((0, jsx_runtime_1.jsx)(react_code_editor_1.CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: FileDetails_1.extensionToLanguage[path_browserify_1.default.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
|
|
147
|
+
glyphMargin: false,
|
|
148
|
+
folding: false,
|
|
149
|
+
// prevents Monaco from handling resizing itself
|
|
150
|
+
// was causing ResizeObserver issues
|
|
151
|
+
automaticLayout: false
|
|
152
|
+
} }, props)));
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
};
|
|
156
|
+
const modal = ((0, jsx_runtime_1.jsxs)(ChatbotModal_1.default, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [(0, jsx_runtime_1.jsx)(react_core_1.ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), (0, jsx_runtime_1.jsx)(react_core_1.ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: (0, jsx_runtime_1.jsxs)(react_core_1.Stack, { className: "pf-chatbot__code-modal-body", children: [(0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-file-details", children: (0, jsx_runtime_1.jsx)(FileDetails_1.default, { fileName: fileName }) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: renderMonacoEditor() })] }) }), (0, jsx_runtime_1.jsxs)(react_core_1.ModalFooter, { className: modalFooterClassName, children: [(0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), (0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
|
|
112
157
|
return modal;
|
|
113
158
|
};
|
|
114
159
|
exports.CodeModal = CodeModal;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
|
|
2
|
+
import { LabelProps } from '@patternfly/react-core';
|
|
3
|
+
export interface FileDetailsLabelProps extends Omit<LabelProps, 'onClose' | 'onClick'> {
|
|
3
4
|
/** Name of file, including extension */
|
|
4
5
|
fileName: string;
|
|
5
6
|
/** Unique id of file */
|
|
@@ -18,6 +18,8 @@ export interface CodeBlockMessageProps {
|
|
|
18
18
|
collapsedText?: string;
|
|
19
19
|
/** Custom actions added to header of code block, after any default actions such as the "copy" action. */
|
|
20
20
|
customActions?: React.ReactNode;
|
|
21
|
+
/** Sets background colors to be appropriate on primary chatbot background */
|
|
22
|
+
isPrimary?: boolean;
|
|
21
23
|
}
|
|
22
|
-
declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, isPrimary, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
25
|
export default CodeBlockMessage;
|
|
@@ -24,7 +24,7 @@ const DEFAULT_EXPANDED_TEXT = 'Show less';
|
|
|
24
24
|
const DEFAULT_COLLAPSED_TEXT = 'Show more';
|
|
25
25
|
const CodeBlockMessage = (_a) => {
|
|
26
26
|
var _b;
|
|
27
|
-
var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions"]);
|
|
27
|
+
var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions, isPrimary } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions", "isPrimary"]);
|
|
28
28
|
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
29
29
|
const [isExpanded, setIsExpanded] = (0, react_1.useState)(false);
|
|
30
30
|
const buttonRef = (0, react_1.useRef)();
|
|
@@ -61,7 +61,7 @@ const CodeBlockMessage = (_a) => {
|
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
if (!String(children).includes('\n')) {
|
|
64
|
-
return ((0, jsx_runtime_1.jsx)("code", Object.assign({}, props, { className:
|
|
64
|
+
return ((0, jsx_runtime_1.jsx)("code", Object.assign({}, props, { className: `pf-chatbot__message-inline-code ${isPrimary ? 'pf-m-primary' : ''}`, children: children })));
|
|
65
65
|
}
|
|
66
66
|
// Setup code block header
|
|
67
67
|
const actions = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_core_1.CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-code-block-language", children: language }), (0, jsx_runtime_1.jsx)(react_core_1.Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? (0, jsx_runtime_1.jsx)(check_icon_1.CheckIcon, {}) : (0, jsx_runtime_1.jsx)(copy_icon_1.CopyIcon, {}) }), (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
|
|
@@ -10,6 +10,7 @@ import QuickResponse from './QuickResponse/QuickResponse';
|
|
|
10
10
|
import { UserFeedbackProps } from './UserFeedback/UserFeedback';
|
|
11
11
|
import { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete';
|
|
12
12
|
import { TableProps } from '@patternfly/react-table';
|
|
13
|
+
import 'highlight.js/styles/vs2015.css';
|
|
13
14
|
import { PluggableList } from 'unified';
|
|
14
15
|
import { ToolResponseProps } from '../ToolResponse';
|
|
15
16
|
import { DeepThinkingProps } from '../DeepThinking';
|
|
@@ -52,17 +53,32 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
52
53
|
/** Name of the user */
|
|
53
54
|
name?: string;
|
|
54
55
|
/** Avatar src for the user */
|
|
55
|
-
avatar
|
|
56
|
+
avatar?: string;
|
|
56
57
|
/** Timestamp for the message */
|
|
57
58
|
timestamp?: string;
|
|
58
59
|
/** Set this to true if message is being loaded */
|
|
59
60
|
isLoading?: boolean;
|
|
60
61
|
/** Array of attachments attached to a message */
|
|
61
62
|
attachments?: MessageAttachment[];
|
|
62
|
-
/** Props for message actions, such as feedback (positive or negative), copy button, edit message, share, and listen
|
|
63
|
+
/** Props for message actions, such as feedback (positive or negative), copy button, edit message, share, and listen.
|
|
64
|
+
* Can be a single actions object or an array of action group objects. When passing an array, you can pass an object of actions or
|
|
65
|
+
* an object that contains an actions property for finer control of selection persistence.
|
|
66
|
+
*/
|
|
63
67
|
actions?: {
|
|
64
68
|
[key: string]: ActionProps;
|
|
65
|
-
}
|
|
69
|
+
} | {
|
|
70
|
+
[key: string]: ActionProps;
|
|
71
|
+
}[] | {
|
|
72
|
+
actions: {
|
|
73
|
+
[key: string]: ActionProps;
|
|
74
|
+
};
|
|
75
|
+
persistActionSelection?: boolean;
|
|
76
|
+
}[];
|
|
77
|
+
/** When true, the selected action will persist even when clicking outside the component.
|
|
78
|
+
* When false (default), clicking outside or clicking another action will deselect the current selection.
|
|
79
|
+
* For finer control of multiple action groups, use persistActionSelection on each group.
|
|
80
|
+
*/
|
|
81
|
+
persistActionSelection?: boolean;
|
|
66
82
|
/** Sources for message */
|
|
67
83
|
sources?: SourcesCardProps;
|
|
68
84
|
/** Label for the English word "AI," used to tag messages with role "bot" */
|
|
@@ -144,6 +160,8 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
144
160
|
toolCall?: ToolCallProps;
|
|
145
161
|
/** Whether user messages default to stripping out images in markdown */
|
|
146
162
|
hasNoImagesInUserMessages?: boolean;
|
|
163
|
+
/** Sets background colors to be appropriate on primary chatbot background */
|
|
164
|
+
isPrimary?: boolean;
|
|
147
165
|
}
|
|
148
166
|
export declare const MessageBase: FunctionComponent<MessageProps>;
|
|
149
167
|
declare const Message: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -46,6 +46,9 @@ const ImageMessage_1 = __importDefault(require("./ImageMessage/ImageMessage"));
|
|
|
46
46
|
const rehype_unwrap_images_1 = __importDefault(require("rehype-unwrap-images"));
|
|
47
47
|
const rehype_external_links_1 = __importDefault(require("rehype-external-links"));
|
|
48
48
|
const rehype_sanitize_1 = __importDefault(require("rehype-sanitize"));
|
|
49
|
+
const rehype_highlight_1 = __importDefault(require("rehype-highlight"));
|
|
50
|
+
// see the full list of styles here: https://highlightjs.org/examples
|
|
51
|
+
require("highlight.js/styles/vs2015.css");
|
|
49
52
|
const LinkMessage_1 = __importDefault(require("./LinkMessage/LinkMessage"));
|
|
50
53
|
const ErrorMessage_1 = __importDefault(require("./ErrorMessage/ErrorMessage"));
|
|
51
54
|
const MessageInput_1 = __importDefault(require("./MessageInput"));
|
|
@@ -55,13 +58,13 @@ const DeepThinking_1 = __importDefault(require("../DeepThinking"));
|
|
|
55
58
|
const SuperscriptMessage_1 = __importDefault(require("./SuperscriptMessage/SuperscriptMessage"));
|
|
56
59
|
const ToolCall_1 = __importDefault(require("../ToolCall"));
|
|
57
60
|
const MessageBase = (_a) => {
|
|
58
|
-
var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages"]);
|
|
61
|
+
var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary"]);
|
|
59
62
|
const [messageText, setMessageText] = (0, react_1.useState)(content);
|
|
60
63
|
(0, react_1.useEffect)(() => {
|
|
61
64
|
setMessageText(content);
|
|
62
65
|
}, [content]);
|
|
63
66
|
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
|
64
|
-
let rehypePlugins = [rehype_unwrap_images_1.default, rehypeMoveImagesOutOfParagraphs_1.rehypeMoveImagesOutOfParagraphs];
|
|
67
|
+
let rehypePlugins = [rehype_unwrap_images_1.default, rehypeMoveImagesOutOfParagraphs_1.rehypeMoveImagesOutOfParagraphs, rehype_highlight_1.default];
|
|
65
68
|
if (openLinkInNewTab) {
|
|
66
69
|
rehypePlugins = rehypePlugins.concat([[rehype_external_links_1.default, { target: '_blank' }, rehype_sanitize_1.default]]);
|
|
67
70
|
}
|
|
@@ -94,13 +97,13 @@ const MessageBase = (_a) => {
|
|
|
94
97
|
p: (props) => {
|
|
95
98
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
96
99
|
const { node } = props, rest = __rest(props, ["node"]);
|
|
97
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, rest));
|
|
100
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, rest, { isPrimary: isPrimary }));
|
|
98
101
|
},
|
|
99
102
|
code: (_a) => {
|
|
100
103
|
var { children } = _a, props = __rest(_a, ["children"]);
|
|
101
104
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
102
105
|
const { node } = props, codeProps = __rest(props, ["node"]);
|
|
103
|
-
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, codeProps, codeBlockProps, { children: children })));
|
|
106
|
+
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, codeProps, codeBlockProps, { isPrimary: isPrimary, children: children })));
|
|
104
107
|
},
|
|
105
108
|
h1: (props) => {
|
|
106
109
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -153,7 +156,7 @@ const MessageBase = (_a) => {
|
|
|
153
156
|
return (0, jsx_runtime_1.jsx)(ListItemMessage_1.default, Object.assign({}, rest));
|
|
154
157
|
},
|
|
155
158
|
// table requires node attribute for calculating headers for mobile breakpoint
|
|
156
|
-
table: (props) => (0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({}, props, tableProps)),
|
|
159
|
+
table: (props) => (0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({}, props, tableProps, { isPrimary: isPrimary })),
|
|
157
160
|
tbody: (props) => {
|
|
158
161
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
159
162
|
const { node } = props, rest = __rest(props, ["node"]);
|
|
@@ -206,7 +209,7 @@ const MessageBase = (_a) => {
|
|
|
206
209
|
};
|
|
207
210
|
const renderMessage = () => {
|
|
208
211
|
if (isLoading) {
|
|
209
|
-
return (0, jsx_runtime_1.jsx)(MessageLoading_1.default, { loadingWord: loadingWord });
|
|
212
|
+
return (0, jsx_runtime_1.jsx)(MessageLoading_1.default, { loadingWord: loadingWord, isPrimary: isPrimary });
|
|
210
213
|
}
|
|
211
214
|
if (isEditable) {
|
|
212
215
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), (0, jsx_runtime_1.jsx)(MessageInput_1.default, Object.assign({ content: messageText, editPlaceholder: editPlaceholder, updateWord: updateWord, cancelWord: cancelWord, onEditUpdate: (event, value) => {
|
|
@@ -216,9 +219,9 @@ const MessageBase = (_a) => {
|
|
|
216
219
|
}
|
|
217
220
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [beforeMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: beforeMainContent }), error ? (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, Object.assign({}, error)) : handleMarkdown()] }));
|
|
218
221
|
};
|
|
219
|
-
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] }), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-response", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), toolResponse && (0, jsx_runtime_1.jsx)(ToolResponse_1.default, Object.assign({}, toolResponse)), deepThinking && (0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, deepThinking)), toolCall && (0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, toolCall)), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && (0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actions }), userFeedbackForm && (0, jsx_runtime_1.jsx)(UserFeedback_1.default, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && ((0, jsx_runtime_1.jsx)(UserFeedbackComplete_1.default, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
222
|
+
return ((0, jsx_runtime_1.jsxs)("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [avatar && ((0, jsx_runtime_1.jsx)(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps))), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-contents", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-meta", children: [name && ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__message-name", children: (0, jsx_runtime_1.jsx)(react_core_1.Truncate, { content: name }) })), role === 'bot' && ((0, jsx_runtime_1.jsx)(react_core_1.Label, { variant: "outline", isCompact: true, children: botWord })), (0, jsx_runtime_1.jsx)(react_core_1.Timestamp, { date: date, children: timestamp })] }), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-response", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: afterMainContent }), toolResponse && (0, jsx_runtime_1.jsx)(ToolResponse_1.default, Object.assign({}, toolResponse)), deepThinking && (0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, deepThinking)), toolCall && (0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, toolCall)), !isLoading && sources && (0, jsx_runtime_1.jsx)(SourcesCard_1.default, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && ((0, jsx_runtime_1.jsx)(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Array.isArray(actions) ? ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__response-actions-groups", children: actions.map((actionGroup, index) => ((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actionGroup.actions || actionGroup, persistActionSelection: persistActionSelection || actionGroup.persistActionSelection }, index))) })) : ((0, jsx_runtime_1.jsx)(ResponseActions_1.default, { actions: actions, persistActionSelection: persistActionSelection })) })), userFeedbackForm && (0, jsx_runtime_1.jsx)(UserFeedback_1.default, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && ((0, jsx_runtime_1.jsx)(UserFeedbackComplete_1.default, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
|
|
220
223
|
var _a;
|
|
221
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachment", children: (0, jsx_runtime_1.jsx)(FileDetailsLabel_1.default, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
|
|
224
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-attachment", children: (0, jsx_runtime_1.jsx)(FileDetailsLabel_1.default, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId, variant: isPrimary ? 'outline' : undefined }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
|
|
222
225
|
}) })), !isLoading && endContent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: endContent })] })] })] })));
|
|
223
226
|
};
|
|
224
227
|
exports.MessageBase = MessageBase;
|
|
@@ -209,6 +209,10 @@ describe('Message', () => {
|
|
|
209
209
|
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./testImg", role: "bot", name: "Bot", content: "Hi" }));
|
|
210
210
|
expect(react_2.screen.getByRole('img')).toHaveAttribute('src', './testImg');
|
|
211
211
|
});
|
|
212
|
+
it('should not render avatar if no avatar prop is passed', () => {
|
|
213
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { role: "bot", name: "Bot", content: "Hi" }));
|
|
214
|
+
expect(react_2.screen.queryByRole('img')).not.toBeInTheDocument();
|
|
215
|
+
});
|
|
212
216
|
it('should render botWord correctly', () => {
|
|
213
217
|
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", botWord: "\u4EBA\u5DE5\u77E5\u80FD" }));
|
|
214
218
|
expect(react_2.screen.getByText('Bot')).toBeTruthy();
|
|
@@ -356,7 +360,7 @@ describe('Message', () => {
|
|
|
356
360
|
expect(react_2.screen.queryByRole('button', { name: /No/i })).toBeFalsy();
|
|
357
361
|
expect(react_2.screen.getByRole('button', { name: /1 more/i }));
|
|
358
362
|
}));
|
|
359
|
-
it('
|
|
363
|
+
it('Renders response actions when a single actions object is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
360
364
|
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: {
|
|
361
365
|
// eslint-disable-next-line no-console
|
|
362
366
|
positive: { onClick: () => console.log('Good response') },
|
|
@@ -374,9 +378,132 @@ describe('Message', () => {
|
|
|
374
378
|
listen: { onClick: () => console.log('Listen') }
|
|
375
379
|
} }));
|
|
376
380
|
ALL_ACTIONS.forEach(({ label }) => {
|
|
377
|
-
expect(react_2.screen.getByRole('button', { name: label })).
|
|
381
|
+
expect(react_2.screen.getByRole('button', { name: label })).toBeVisible();
|
|
382
|
+
});
|
|
383
|
+
}));
|
|
384
|
+
it('Renders response actions when an array of actions objects is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
385
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: [
|
|
386
|
+
{
|
|
387
|
+
// eslint-disable-next-line no-console
|
|
388
|
+
positive: { onClick: () => console.log('Good response') },
|
|
389
|
+
// eslint-disable-next-line no-console
|
|
390
|
+
negative: { onClick: () => console.log('Bad response') }
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
// eslint-disable-next-line no-console
|
|
394
|
+
copy: { onClick: () => console.log('Copy') },
|
|
395
|
+
// eslint-disable-next-line no-console
|
|
396
|
+
edit: { onClick: () => console.log('Edit') },
|
|
397
|
+
// eslint-disable-next-line no-console
|
|
398
|
+
share: { onClick: () => console.log('Share') },
|
|
399
|
+
// eslint-disable-next-line no-console
|
|
400
|
+
download: { onClick: () => console.log('Download') }
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
// eslint-disable-next-line no-console
|
|
404
|
+
listen: { onClick: () => console.log('Listen') }
|
|
405
|
+
}
|
|
406
|
+
] }));
|
|
407
|
+
ALL_ACTIONS.forEach(({ label }) => {
|
|
408
|
+
expect(react_2.screen.getByRole('button', { name: label })).toBeVisible();
|
|
409
|
+
});
|
|
410
|
+
}));
|
|
411
|
+
it('Renders response actions when an array of objects containing actions objects is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
412
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: [
|
|
413
|
+
{
|
|
414
|
+
actions: {
|
|
415
|
+
// eslint-disable-next-line no-console
|
|
416
|
+
positive: { onClick: () => console.log('Good response') },
|
|
417
|
+
// eslint-disable-next-line no-console
|
|
418
|
+
negative: { onClick: () => console.log('Bad response') }
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
actions: {
|
|
423
|
+
// eslint-disable-next-line no-console
|
|
424
|
+
copy: { onClick: () => console.log('Copy') },
|
|
425
|
+
// eslint-disable-next-line no-console
|
|
426
|
+
edit: { onClick: () => console.log('Edit') },
|
|
427
|
+
// eslint-disable-next-line no-console
|
|
428
|
+
share: { onClick: () => console.log('Share') },
|
|
429
|
+
// eslint-disable-next-line no-console
|
|
430
|
+
download: { onClick: () => console.log('Download') }
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
actions: {
|
|
435
|
+
// eslint-disable-next-line no-console
|
|
436
|
+
listen: { onClick: () => console.log('Listen') }
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
] }));
|
|
440
|
+
ALL_ACTIONS.forEach(({ label }) => {
|
|
441
|
+
expect(react_2.screen.getByRole('button', { name: label })).toBeVisible();
|
|
378
442
|
});
|
|
379
443
|
}));
|
|
444
|
+
it('should handle persistActionSelection correctly when a single actions object is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
445
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Test message", persistActionSelection: true, actions: {
|
|
446
|
+
positive: { onClick: jest.fn() },
|
|
447
|
+
negative: { onClick: jest.fn() }
|
|
448
|
+
} }));
|
|
449
|
+
const goodBtn = react_2.screen.getByRole('button', { name: /Good response/i });
|
|
450
|
+
const badBtn = react_2.screen.getByRole('button', { name: /Bad response/i });
|
|
451
|
+
yield user_event_1.default.click(goodBtn);
|
|
452
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
453
|
+
yield user_event_1.default.click(react_2.screen.getByText('Test message'));
|
|
454
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
455
|
+
yield user_event_1.default.click(badBtn);
|
|
456
|
+
expect(react_2.screen.getByRole('button', { name: /Bad response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
457
|
+
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
458
|
+
}));
|
|
459
|
+
it('should handle persistActionSelection correctly when an array of actions objects is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
460
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Test message", persistActionSelection: true, actions: [
|
|
461
|
+
{
|
|
462
|
+
positive: { onClick: jest.fn() },
|
|
463
|
+
negative: { onClick: jest.fn() }
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
copy: { onClick: jest.fn() }
|
|
467
|
+
}
|
|
468
|
+
] }));
|
|
469
|
+
const goodBtn = react_2.screen.getByRole('button', { name: /Good response/i });
|
|
470
|
+
const copyBtn = react_2.screen.getByRole('button', { name: /Copy/i });
|
|
471
|
+
yield user_event_1.default.click(goodBtn);
|
|
472
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
473
|
+
yield user_event_1.default.click(react_2.screen.getByText('Test message'));
|
|
474
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
475
|
+
yield user_event_1.default.click(copyBtn);
|
|
476
|
+
expect(react_2.screen.getByRole('button', { name: /Copied/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
477
|
+
yield user_event_1.default.click(react_2.screen.getByText('Test message'));
|
|
478
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
479
|
+
expect(react_2.screen.getByRole('button', { name: /Copied/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
480
|
+
}));
|
|
481
|
+
it('should handle persistActionSelection correctly when an array of objects containing actions objects is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
482
|
+
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Test message", actions: [
|
|
483
|
+
{
|
|
484
|
+
actions: {
|
|
485
|
+
positive: { onClick: jest.fn() },
|
|
486
|
+
negative: { onClick: jest.fn() }
|
|
487
|
+
},
|
|
488
|
+
persistActionSelection: true
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
actions: {
|
|
492
|
+
copy: { onClick: jest.fn() }
|
|
493
|
+
},
|
|
494
|
+
persistActionSelection: false
|
|
495
|
+
}
|
|
496
|
+
] }));
|
|
497
|
+
const goodBtn = react_2.screen.getByRole('button', { name: /Good response/i });
|
|
498
|
+
const copyBtn = react_2.screen.getByRole('button', { name: /Copy/i });
|
|
499
|
+
yield user_event_1.default.click(goodBtn);
|
|
500
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
501
|
+
yield user_event_1.default.click(copyBtn);
|
|
502
|
+
expect(react_2.screen.getByRole('button', { name: /Copied/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
503
|
+
yield user_event_1.default.click(react_2.screen.getByText('Test message'));
|
|
504
|
+
expect(react_2.screen.getByRole('button', { name: /Good response recorded/i })).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
505
|
+
expect(copyBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
506
|
+
}));
|
|
380
507
|
it('should not show actions if loading', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
381
508
|
(0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", isLoading: true, actions: {
|
|
382
509
|
// eslint-disable-next-line no-console
|
|
@@ -831,4 +958,36 @@ describe('Message', () => {
|
|
|
831
958
|
expect(react_2.screen.getByText('Thought for 3 seconds')).toBeTruthy();
|
|
832
959
|
expect(react_2.screen.getByText("Here's why I said this.")).toBeTruthy();
|
|
833
960
|
});
|
|
961
|
+
it('should handle isPrimary correctly for inline code when it is true', () => {
|
|
962
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: INLINE_CODE, isPrimary: true }));
|
|
963
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
964
|
+
});
|
|
965
|
+
it('should handle isPrimary correctly for inline code when it is false', () => {
|
|
966
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: INLINE_CODE }));
|
|
967
|
+
expect(container.querySelector('.pf-m-primary')).toBeFalsy();
|
|
968
|
+
});
|
|
969
|
+
it('should handle isPrimary correctly for table when it is true', () => {
|
|
970
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: TABLE, isPrimary: true }));
|
|
971
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
972
|
+
});
|
|
973
|
+
it('should handle isPrimary correctly for table when it is false', () => {
|
|
974
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: TABLE }));
|
|
975
|
+
expect(container.querySelector('.pf-m-primary')).toBeFalsy();
|
|
976
|
+
});
|
|
977
|
+
it('should handle isPrimary correctly for loading when it is true', () => {
|
|
978
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "", isPrimary: true, isLoading: true }));
|
|
979
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
980
|
+
});
|
|
981
|
+
it('should handle isPrimary correctly for loading when it is false', () => {
|
|
982
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "", isLoading: true }));
|
|
983
|
+
expect(container.querySelector('.pf-m-primary')).toBeFalsy();
|
|
984
|
+
});
|
|
985
|
+
it('should handle isPrimary correctly for attachments when it is true', () => {
|
|
986
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "", isPrimary: true, attachments: [{ name: 'testAttachment' }] }));
|
|
987
|
+
expect(container.querySelector('.pf-m-outline')).toBeTruthy();
|
|
988
|
+
});
|
|
989
|
+
it('should handle isPrimary correctly for attachments when it is false', () => {
|
|
990
|
+
const { container } = (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "", attachments: [{ name: 'testAttachment' }] }));
|
|
991
|
+
expect(container.querySelector('.pf-m-outline')).toBeFalsy();
|
|
992
|
+
});
|
|
834
993
|
});
|