@patternfly/chatbot 6.7.1 → 6.8.0-prerelease.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
- package/dist/cjs/Message/Message.test.js +31 -14
- package/dist/cjs/Message/TableMessage/TableCellContent.d.ts +8 -0
- package/dist/cjs/Message/TableMessage/TableCellContent.js +9 -0
- package/dist/cjs/Message/TableMessage/TdMessage.js +5 -1
- package/dist/cjs/Message/TableMessage/ThMessage.js +5 -1
- package/dist/cjs/ResponseActions/ResponseActions.js +21 -5
- package/dist/cjs/ResponseActions/ResponseActions.test.js +33 -29
- package/dist/cjs/SourcesCardBase/SourcesCardBase.js +1 -1
- package/dist/cjs/SourcesCardBase/SourcesCardBase.test.js +4 -4
- package/dist/css/main.css +7 -14
- package/dist/css/main.css.map +1 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
- package/dist/esm/Message/Message.test.js +31 -14
- package/dist/esm/Message/TableMessage/TableCellContent.d.ts +8 -0
- package/dist/esm/Message/TableMessage/TableCellContent.js +7 -0
- package/dist/esm/Message/TableMessage/TdMessage.js +2 -1
- package/dist/esm/Message/TableMessage/ThMessage.js +2 -1
- package/dist/esm/ResponseActions/ResponseActions.js +22 -6
- package/dist/esm/ResponseActions/ResponseActions.test.js +33 -29
- package/dist/esm/SourcesCardBase/SourcesCardBase.js +1 -1
- package/dist/esm/SourcesCardBase/SourcesCardBase.test.js +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarAttach.tsx +11 -7
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx +46 -35
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +7 -1
- package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx +4 -2
- package/src/AttachMenu/AttachMenu.scss +0 -9
- package/src/Chatbot/Chatbot.scss +0 -7
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +1 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +7 -1
- package/src/ChatbotHeader/ChatbotHeader.scss +1 -0
- package/src/ChatbotToggle/ChatbotToggle.scss +1 -1
- package/src/Message/Message.test.tsx +42 -14
- package/src/Message/TableMessage/TableCellContent.tsx +9 -0
- package/src/Message/TableMessage/TdMessage.tsx +6 -1
- package/src/Message/TableMessage/ThMessage.tsx +6 -1
- package/src/ResponseActions/ResponseActions.test.tsx +33 -29
- package/src/ResponseActions/ResponseActions.tsx +37 -18
- package/src/SourcesCard/SourcesCard.scss +5 -0
- package/src/SourcesCardBase/SourcesCardBase.test.tsx +4 -4
- package/src/SourcesCardBase/SourcesCardBase.tsx +12 -3
package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx
CHANGED
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
SelectList,
|
|
11
11
|
SelectOption
|
|
12
12
|
} from '@patternfly/react-core';
|
|
13
|
-
import
|
|
13
|
+
import RhUiAddIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-icon';
|
|
14
|
+
import RhUiClipboardIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-clipboard-icon';
|
|
15
|
+
import RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';
|
|
16
|
+
import RhUiUploadIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-upload-icon';
|
|
14
17
|
import { useDropzone } from 'react-dropzone';
|
|
15
18
|
|
|
16
19
|
export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
|
|
@@ -45,43 +48,51 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
|
|
|
45
48
|
};
|
|
46
49
|
|
|
47
50
|
const firstMenuItems: ReactNode = (
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
Logs
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
YAML - Status
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
YAML - All contents
|
|
57
|
-
|
|
51
|
+
<>
|
|
52
|
+
<DropdownList>
|
|
53
|
+
<DropdownItem value="Logs" id="logs" icon={<RhUiClipboardIcon />}>
|
|
54
|
+
Logs
|
|
55
|
+
</DropdownItem>
|
|
56
|
+
<DropdownItem value="YAML - Status" id="yaml-status" icon={<RhUiCodeIcon />}>
|
|
57
|
+
YAML - Status
|
|
58
|
+
</DropdownItem>
|
|
59
|
+
<DropdownItem value="YAML - All contents" id="yaml-all" icon={<RhUiCodeIcon />}>
|
|
60
|
+
YAML - All contents
|
|
61
|
+
</DropdownItem>
|
|
62
|
+
</DropdownList>
|
|
58
63
|
<Divider key="divider" />
|
|
59
|
-
<
|
|
60
|
-
Upload from computer
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
<DropdownList>
|
|
65
|
+
<DropdownItem value="Upload from computer" id="upload" icon={<RhUiUploadIcon />} onClick={open}>
|
|
66
|
+
Upload from computer
|
|
67
|
+
</DropdownItem>
|
|
68
|
+
</DropdownList>
|
|
69
|
+
</>
|
|
63
70
|
);
|
|
64
71
|
|
|
65
72
|
const secondMenuItems: ReactNode = (
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Logs
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
YAML - Status
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
YAML - All contents
|
|
79
|
-
|
|
73
|
+
<>
|
|
74
|
+
<DropdownList>
|
|
75
|
+
<DropdownItem value="canvas" id="canvas">
|
|
76
|
+
{showCanvasLabel ? 'Disable' : 'Enable'} Canvas
|
|
77
|
+
</DropdownItem>
|
|
78
|
+
<Divider key="divider-1" />
|
|
79
|
+
<DropdownItem value="Logs" id="logs" icon={<RhUiClipboardIcon />}>
|
|
80
|
+
Logs
|
|
81
|
+
</DropdownItem>
|
|
82
|
+
<DropdownItem value="YAML - Status" id="yaml-status" icon={<RhUiCodeIcon />}>
|
|
83
|
+
YAML - Status
|
|
84
|
+
</DropdownItem>
|
|
85
|
+
<DropdownItem value="YAML - All contents" id="yaml-all" icon={<RhUiCodeIcon />}>
|
|
86
|
+
YAML - All contents
|
|
87
|
+
</DropdownItem>
|
|
88
|
+
</DropdownList>
|
|
80
89
|
<Divider key="divider-2" />
|
|
81
|
-
<
|
|
82
|
-
Upload from computer
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
<DropdownList>
|
|
91
|
+
<DropdownItem value="Upload from computer" id="upload" icon={<RhUiUploadIcon />} onClick={open}>
|
|
92
|
+
Upload from computer
|
|
93
|
+
</DropdownItem>
|
|
94
|
+
</DropdownList>
|
|
95
|
+
</>
|
|
85
96
|
);
|
|
86
97
|
|
|
87
98
|
const modelOptions = ['GPT-4', 'GPT-3.5', 'Claude', 'Llama 2'];
|
|
@@ -110,7 +121,7 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
|
|
|
110
121
|
}}
|
|
111
122
|
buttonProps={{
|
|
112
123
|
attach: {
|
|
113
|
-
icon: <
|
|
124
|
+
icon: <RhUiAddIcon />,
|
|
114
125
|
tooltipContent: 'Message actions',
|
|
115
126
|
'aria-label': 'Message actions'
|
|
116
127
|
}
|
|
@@ -140,7 +151,7 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
|
|
|
140
151
|
}}
|
|
141
152
|
buttonProps={{
|
|
142
153
|
attach: {
|
|
143
|
-
icon: <
|
|
154
|
+
icon: <RhUiAddIcon />,
|
|
144
155
|
tooltipContent: 'Message actions',
|
|
145
156
|
'aria-label': 'Message actions'
|
|
146
157
|
}
|
|
@@ -70,7 +70,13 @@ import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar';
|
|
|
70
70
|
import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem';
|
|
71
71
|
import { ChatbotModal } from '@patternfly/chatbot/dist/dynamic/ChatbotModal';
|
|
72
72
|
import SettingsForm from '@patternfly/chatbot/dist/dynamic/Settings';
|
|
73
|
-
import
|
|
73
|
+
import RhUiAttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-attention-bell-icon';
|
|
74
|
+
import RhUiCalendarIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-calendar-icon';
|
|
75
|
+
import RhUiClipboardIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-clipboard-icon';
|
|
76
|
+
import RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';
|
|
77
|
+
import RhUiAddIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-icon';
|
|
78
|
+
import { ThumbtackIcon } from '@patternfly/react-icons';
|
|
79
|
+
import RhUiUploadIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-upload-icon';
|
|
74
80
|
import { useDropzone } from 'react-dropzone';
|
|
75
81
|
|
|
76
82
|
import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
|
package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx
CHANGED
|
@@ -18,7 +18,7 @@ import ChatbotFooter from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';
|
|
|
18
18
|
import MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar';
|
|
19
19
|
import MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox';
|
|
20
20
|
import Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message';
|
|
21
|
-
import ChatbotHeader, { ChatbotHeaderMain } from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
|
|
21
|
+
import ChatbotHeader, { ChatbotHeaderMain, ChatbotHeaderTitle } from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
|
|
22
22
|
import Compare from '@patternfly/chatbot/dist/dynamic/Compare';
|
|
23
23
|
import { BarsIcon } from '@patternfly/react-icons';
|
|
24
24
|
import userAvatar from '../Messages/user_avatar.svg';
|
|
@@ -115,7 +115,9 @@ export const CompareChild = ({ name, input, hasNewInput, setIsSendButtonDisabled
|
|
|
115
115
|
return (
|
|
116
116
|
<Chatbot displayMode={displayMode}>
|
|
117
117
|
<ChatbotHeader>
|
|
118
|
-
<ChatbotHeaderMain>
|
|
118
|
+
<ChatbotHeaderMain>
|
|
119
|
+
<ChatbotHeaderTitle>{name}</ChatbotHeaderTitle>
|
|
120
|
+
</ChatbotHeaderMain>
|
|
119
121
|
</ChatbotHeader>
|
|
120
122
|
<ChatbotContent>
|
|
121
123
|
<MessageBox ariaLabel={`Scrollable message log for ${name}`} announcement={announcement}>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
.pf-chatbot__menu.pf-v6-c-menu {
|
|
2
|
-
--pf-v6-c-menu--BorderRadius: var(--pf-t--global--border--radius--large);
|
|
3
2
|
--pf-v6-c-menu__list-item--hover--BackgroundColor: var(--pf-t--global--background--color--secondary--default);
|
|
4
3
|
}
|
|
5
4
|
|
|
@@ -31,10 +30,6 @@
|
|
|
31
30
|
--pf-v6-c-menu__item-main--ColumnGap: var(--pf-t--global--spacer--md);
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
.pf-v6-c-menu__list {
|
|
35
|
-
padding: 0rem var(--pf-t--global--spacer--md) 0rem var(--pf-t--global--spacer--md);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
33
|
/* handles hover state, which uses a background */
|
|
39
34
|
.pf-v6-c-menu__list-item {
|
|
40
35
|
border-radius: var(--pf-t--global--border--radius--small);
|
|
@@ -55,8 +50,4 @@
|
|
|
55
50
|
.pf-v6-c-menu__item-description {
|
|
56
51
|
font-weight: var(--pf-t--global--font--weight--body--bold);
|
|
57
52
|
}
|
|
58
|
-
|
|
59
|
-
.pf-v6-c-divider {
|
|
60
|
-
padding: 0 var(--pf-t--global--spacer--md) 0 var(--pf-t--global--spacer--md);
|
|
61
|
-
}
|
|
62
53
|
}
|
package/src/Chatbot/Chatbot.scss
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
background-color: var(--pf-t--global--background--color--floating--secondary--default);
|
|
13
13
|
border-radius: var(--pf-t--global--border--radius--medium);
|
|
14
14
|
box-shadow: var(--pf-t--global--box-shadow--lg);
|
|
15
|
-
font-size: var(--pf-t--global--font--size--md);
|
|
16
15
|
z-index: var(--pf-t--global--z-index--md);
|
|
17
16
|
-webkit-font-smoothing: antialiased;
|
|
18
17
|
-moz-osx-font-smoothing: grayscale;
|
|
@@ -178,9 +177,3 @@
|
|
|
178
177
|
}
|
|
179
178
|
}
|
|
180
179
|
|
|
181
|
-
// ============================================================================
|
|
182
|
-
// Information density styles
|
|
183
|
-
// ============================================================================
|
|
184
|
-
.pf-chatbot.pf-m-compact {
|
|
185
|
-
font-size: var(--pf-t--global--font--size--sm);
|
|
186
|
-
}
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
// Drawer menu
|
|
50
50
|
// ----------------------------------------------------------------------------
|
|
51
|
-
.pf-v6-c-menu {
|
|
51
|
+
.pf-v6-c-menu.pf-chatbot__history-menu {
|
|
52
52
|
--pf-v6-c-menu--PaddingBlockStart: 0;
|
|
53
53
|
--pf-v6-c-menu--BackgroundColor: var(--pf-t--global--background--color--floating--default);
|
|
54
54
|
// override high contrast style
|
|
@@ -290,7 +290,13 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
290
290
|
return <HistoryEmptyState {...noResultsState} />;
|
|
291
291
|
}
|
|
292
292
|
return (
|
|
293
|
-
<Menu
|
|
293
|
+
<Menu
|
|
294
|
+
className="pf-chatbot__history-menu"
|
|
295
|
+
isPlain
|
|
296
|
+
onSelect={onSelectActiveItem}
|
|
297
|
+
activeItemId={activeItemId}
|
|
298
|
+
{...menuProps}
|
|
299
|
+
>
|
|
294
300
|
<MenuContent {...menuContentProps}>{buildConversations()}</MenuContent>
|
|
295
301
|
</Menu>
|
|
296
302
|
);
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
&--secondary {
|
|
35
|
-
--pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--secondary--default);
|
|
35
|
+
--pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--floating--secondary--default);
|
|
36
36
|
--pf-v6-c-button--m-plain--hover--BackgroundColor: var(--pf-t--global--background--color--secondary--hover);
|
|
37
37
|
--pf-v6-c-button--m-plain--m-clicked--BackgroundColor: var(--pf-t--global--background--color--secondary--clicked);
|
|
38
38
|
|
|
@@ -11,15 +11,18 @@ import { DeepThinkingProps } from '../DeepThinking';
|
|
|
11
11
|
|
|
12
12
|
// Mock the icon components
|
|
13
13
|
jest.mock('@patternfly/react-icons', () => ({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
RhUiLikeIcon: () => <div>RhUiLikeIcon</div>,
|
|
15
|
+
RhUiLikeFillIcon: () => <div>RhUiLikeFillIcon</div>,
|
|
16
|
+
RhUiDislikeIcon: () => <div>RhUiDislikeIcon</div>,
|
|
17
|
+
RhUiDislikeFillIcon: () => <div>RhUiDislikeFillIcon</div>,
|
|
18
|
+
RhUiCopyIcon: () => <div>RhUiCopyIcon</div>,
|
|
19
|
+
RhUiCopyFillIcon: () => <div>RhUiCopyFillIcon</div>,
|
|
20
|
+
RhUiEditIcon: () => <div>RhUiEditIcon</div>,
|
|
21
|
+
RhUiEditFillIcon: () => <div>RhUiEditFillIcon</div>,
|
|
22
|
+
RhUiVolumeUpIcon: () => <div>RhUiVolumeUpIcon</div>,
|
|
23
|
+
RhUiVolumeUpFillIcon: () => <div>RhUiVolumeUpFillIcon</div>,
|
|
24
|
+
RhUiExportIcon: () => <div>RhUiExportIcon</div>,
|
|
25
|
+
RhUiExportFillIcon: () => <div>RhUiExportFillIcon</div>,
|
|
23
26
|
CheckIcon: () => <div>CheckIcon</div>,
|
|
24
27
|
CloseIcon: () => <div>CloseIcon</div>,
|
|
25
28
|
ExternalLinkSquareAltIcon: () => <div>ExternalLinkSquareAltIcon</div>,
|
|
@@ -118,6 +121,13 @@ const TABLE = `
|
|
|
118
121
|
|
|
119
122
|
`;
|
|
120
123
|
|
|
124
|
+
const TABLE_WITH_INLINE_CODE = `
|
|
125
|
+
| Status | Finding |
|
|
126
|
+
|---|---|
|
|
127
|
+
| \`1/1 Running\`, 0 restarts | Healthy — no crashes |
|
|
128
|
+
| \`1/1 Ready\` | Desired replicas met |
|
|
129
|
+
`;
|
|
130
|
+
|
|
121
131
|
const ONE_COLUMN_TABLE = `
|
|
122
132
|
|
|
123
133
|
| Column 1 |
|
|
@@ -1041,6 +1051,24 @@ describe('Message', () => {
|
|
|
1041
1051
|
render(<Message avatar="./img" role="user" name="User" content={TABLE} tableProps={{ 'aria-label': 'Test' }} />);
|
|
1042
1052
|
expect(screen.getByRole('grid', { name: /Test/i })).toBeTruthy();
|
|
1043
1053
|
});
|
|
1054
|
+
it('should wrap table cell content so inline code does not break grid layout', () => {
|
|
1055
|
+
render(
|
|
1056
|
+
<Message
|
|
1057
|
+
avatar="./img"
|
|
1058
|
+
role="user"
|
|
1059
|
+
name="User"
|
|
1060
|
+
content={TABLE_WITH_INLINE_CODE}
|
|
1061
|
+
tableProps={{ 'aria-label': 'Inline code table' }}
|
|
1062
|
+
/>
|
|
1063
|
+
);
|
|
1064
|
+
const statusCell = screen.getByRole('cell', { name: /1\/1 Running/i });
|
|
1065
|
+
expect(statusCell.querySelector(':scope > .pf-chatbot__message-table-cell-content')).toBeTruthy();
|
|
1066
|
+
expect(statusCell.querySelector(':scope > code')).toBeFalsy();
|
|
1067
|
+
expect(statusCell.querySelector('.pf-chatbot__message-inline-code')).toBeTruthy();
|
|
1068
|
+
expect(
|
|
1069
|
+
screen.getByRole('columnheader', { name: /Status/i }).querySelector('.pf-chatbot__message-table-cell-content')
|
|
1070
|
+
).toBeTruthy();
|
|
1071
|
+
});
|
|
1044
1072
|
it('should render footnote correctly', () => {
|
|
1045
1073
|
render(<Message avatar="./img" role="user" name="User" content={FOOTNOTE} />);
|
|
1046
1074
|
expect(screen.getByText(/This is some text with a footnote/i)).toBeTruthy();
|
|
@@ -1398,12 +1426,12 @@ describe('Message', () => {
|
|
|
1398
1426
|
/>
|
|
1399
1427
|
);
|
|
1400
1428
|
|
|
1401
|
-
expect(screen.getByText('
|
|
1429
|
+
expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
|
|
1402
1430
|
|
|
1403
1431
|
await user.click(screen.getByRole('button', { name: /Good response/i }));
|
|
1404
1432
|
|
|
1405
|
-
expect(screen.getByText('
|
|
1406
|
-
expect(screen.queryByText('
|
|
1433
|
+
expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
|
|
1434
|
+
expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
|
|
1407
1435
|
});
|
|
1408
1436
|
|
|
1409
1437
|
it('should swap icons when useFilledIconsOnClick is true', async () => {
|
|
@@ -1424,8 +1452,8 @@ describe('Message', () => {
|
|
|
1424
1452
|
|
|
1425
1453
|
await user.click(screen.getByRole('button', { name: /Good response/i }));
|
|
1426
1454
|
|
|
1427
|
-
expect(screen.getByText('
|
|
1428
|
-
expect(screen.queryByText('
|
|
1455
|
+
expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
|
|
1456
|
+
expect(screen.queryByText('RhUiLikeIcon')).not.toBeInTheDocument();
|
|
1429
1457
|
});
|
|
1430
1458
|
|
|
1431
1459
|
it('should apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is true', () => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps table cell content in a single element so phrasing content (e.g. inline
|
|
3
|
+
* code mixed with text) is not a direct child of td/th.
|
|
4
|
+
*/
|
|
5
|
+
const TableCellContent = ({ children }: { children?: React.ReactNode }) => (
|
|
6
|
+
<span className="pf-chatbot__message-table-cell-content">{children}</span>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default TableCellContent;
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import { ExtraProps } from 'react-markdown';
|
|
6
6
|
import { Td, TdProps } from '@patternfly/react-table';
|
|
7
|
+
import TableCellContent from './TableCellContent';
|
|
7
8
|
|
|
8
|
-
const TdMessage = ({ children, ...props }: Omit<TdProps, 'ref'> & ExtraProps) =>
|
|
9
|
+
const TdMessage = ({ children, ...props }: Omit<TdProps, 'ref'> & ExtraProps) => (
|
|
10
|
+
<Td {...props}>
|
|
11
|
+
<TableCellContent>{children}</TableCellContent>
|
|
12
|
+
</Td>
|
|
13
|
+
);
|
|
9
14
|
|
|
10
15
|
export default TdMessage;
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import { ExtraProps } from 'react-markdown';
|
|
6
6
|
import { Th, ThProps } from '@patternfly/react-table';
|
|
7
|
+
import TableCellContent from './TableCellContent';
|
|
7
8
|
|
|
8
|
-
const ThMessage = ({ children, ...props }: Omit<ThProps, 'ref'> & ExtraProps) =>
|
|
9
|
+
const ThMessage = ({ children, ...props }: Omit<ThProps, 'ref'> & ExtraProps) => (
|
|
10
|
+
<Th {...props}>
|
|
11
|
+
<TableCellContent>{children}</TableCellContent>
|
|
12
|
+
</Th>
|
|
13
|
+
);
|
|
9
14
|
|
|
10
15
|
export default ThMessage;
|
|
@@ -7,17 +7,21 @@ import Message from '../Message';
|
|
|
7
7
|
|
|
8
8
|
// Mock the icon components
|
|
9
9
|
jest.mock('@patternfly/react-icons', () => ({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
RhUiLikeIcon: () => <div>RhUiLikeIcon</div>,
|
|
11
|
+
RhUiLikeFillIcon: () => <div>RhUiLikeFillIcon</div>,
|
|
12
|
+
RhUiDislikeIcon: () => <div>RhUiDislikeIcon</div>,
|
|
13
|
+
RhUiDislikeFillIcon: () => <div>RhUiDislikeFillIcon</div>,
|
|
14
|
+
RhUiCopyIcon: () => <div>RhUiCopyIcon</div>,
|
|
15
|
+
RhUiCopyFillIcon: () => <div>RhUiCopyFillIcon</div>,
|
|
16
|
+
RhUiEditIcon: () => <div>RhUiEditIcon</div>,
|
|
17
|
+
RhUiEditFillIcon: () => <div>RhUiEditFillIcon</div>,
|
|
18
|
+
RhUiVolumeUpIcon: () => <div>RhUiVolumeUpIcon</div>,
|
|
19
|
+
RhUiVolumeUpFillIcon: () => <div>RhUiVolumeUpFillIcon</div>,
|
|
20
|
+
RhUiExportIcon: () => <div>RhUiExportIcon</div>,
|
|
21
|
+
RhUiExportFillIcon: () => <div>RhUiExportFillIcon</div>,
|
|
15
22
|
DownloadIcon: () => <div>DownloadIcon</div>,
|
|
16
23
|
InfoCircleIcon: () => <div>InfoCircleIcon</div>,
|
|
17
|
-
RedoIcon: () => <div>RedoIcon</div
|
|
18
|
-
ExternalLinkAltIcon: () => <div>ExternalLinkAltIcon</div>,
|
|
19
|
-
VolumeUpIcon: () => <div>VolumeUpIcon</div>,
|
|
20
|
-
PencilAltIcon: () => <div>PencilAltIcon</div>
|
|
24
|
+
RedoIcon: () => <div>RedoIcon</div>
|
|
21
25
|
}));
|
|
22
26
|
|
|
23
27
|
const ALL_ACTIONS = [
|
|
@@ -507,11 +511,11 @@ describe('ResponseActions', () => {
|
|
|
507
511
|
/>
|
|
508
512
|
);
|
|
509
513
|
|
|
510
|
-
expect(screen.getByText('
|
|
511
|
-
expect(screen.getByText('
|
|
514
|
+
expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
|
|
515
|
+
expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
|
|
512
516
|
|
|
513
|
-
expect(screen.queryByText('
|
|
514
|
-
expect(screen.queryByText('
|
|
517
|
+
expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
|
|
518
|
+
expect(screen.queryByText('RhUiDislikeFillIcon')).not.toBeInTheDocument();
|
|
515
519
|
});
|
|
516
520
|
|
|
517
521
|
describe('positive actions', () => {
|
|
@@ -529,8 +533,8 @@ describe('ResponseActions', () => {
|
|
|
529
533
|
|
|
530
534
|
await user.click(screen.getByRole('button', { name: 'Good response' }));
|
|
531
535
|
|
|
532
|
-
expect(screen.getByText('
|
|
533
|
-
expect(screen.queryByText('
|
|
536
|
+
expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
|
|
537
|
+
expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
|
|
534
538
|
});
|
|
535
539
|
|
|
536
540
|
it('should swap positive icon from outline to filled when clicked with useFilledIconsOnClick', async () => {
|
|
@@ -547,8 +551,8 @@ describe('ResponseActions', () => {
|
|
|
547
551
|
|
|
548
552
|
await user.click(screen.getByRole('button', { name: 'Good response' }));
|
|
549
553
|
|
|
550
|
-
expect(screen.getByText('
|
|
551
|
-
expect(screen.queryByText('
|
|
554
|
+
expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
|
|
555
|
+
expect(screen.queryByText('RhUiLikeIcon')).not.toBeInTheDocument();
|
|
552
556
|
});
|
|
553
557
|
|
|
554
558
|
it('should revert positive icon to outline icon when clicking outside', async () => {
|
|
@@ -567,10 +571,10 @@ describe('ResponseActions', () => {
|
|
|
567
571
|
);
|
|
568
572
|
|
|
569
573
|
await user.click(screen.getByRole('button', { name: 'Good response' }));
|
|
570
|
-
expect(screen.getByText('
|
|
574
|
+
expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
|
|
571
575
|
|
|
572
576
|
await user.click(screen.getByTestId('outside'));
|
|
573
|
-
expect(screen.getByText('
|
|
577
|
+
expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
|
|
574
578
|
});
|
|
575
579
|
|
|
576
580
|
it('should not revert positive icon to outline icon when clicking outside if persistActionSelection is true', async () => {
|
|
@@ -590,10 +594,10 @@ describe('ResponseActions', () => {
|
|
|
590
594
|
);
|
|
591
595
|
|
|
592
596
|
await user.click(screen.getByRole('button', { name: 'Good response' }));
|
|
593
|
-
expect(screen.getByText('
|
|
597
|
+
expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
|
|
594
598
|
|
|
595
599
|
await user.click(screen.getByTestId('outside'));
|
|
596
|
-
expect(screen.getByText('
|
|
600
|
+
expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
|
|
597
601
|
});
|
|
598
602
|
|
|
599
603
|
describe('negative actions', () => {
|
|
@@ -611,8 +615,8 @@ describe('ResponseActions', () => {
|
|
|
611
615
|
|
|
612
616
|
await user.click(screen.getByRole('button', { name: 'Bad response' }));
|
|
613
617
|
|
|
614
|
-
expect(screen.getByText('
|
|
615
|
-
expect(screen.queryByText('
|
|
618
|
+
expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
|
|
619
|
+
expect(screen.queryByText('RhUiDislikeFillIcon')).not.toBeInTheDocument();
|
|
616
620
|
});
|
|
617
621
|
|
|
618
622
|
it('should swap negative icon from outline to filled when clicked with useFilledIconsOnClick', async () => {
|
|
@@ -629,8 +633,8 @@ describe('ResponseActions', () => {
|
|
|
629
633
|
|
|
630
634
|
await user.click(screen.getByRole('button', { name: 'Bad response' }));
|
|
631
635
|
|
|
632
|
-
expect(screen.getByText('
|
|
633
|
-
expect(screen.queryByText('
|
|
636
|
+
expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
|
|
637
|
+
expect(screen.queryByText('RhUiDislikeIcon')).not.toBeInTheDocument();
|
|
634
638
|
});
|
|
635
639
|
|
|
636
640
|
it('should revert negative icon to outline when clicking outside', async () => {
|
|
@@ -649,10 +653,10 @@ describe('ResponseActions', () => {
|
|
|
649
653
|
);
|
|
650
654
|
|
|
651
655
|
await user.click(screen.getByRole('button', { name: 'Bad response' }));
|
|
652
|
-
expect(screen.getByText('
|
|
656
|
+
expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
|
|
653
657
|
|
|
654
658
|
await user.click(screen.getByTestId('outside'));
|
|
655
|
-
expect(screen.getByText('
|
|
659
|
+
expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
|
|
656
660
|
});
|
|
657
661
|
|
|
658
662
|
it('should not revert negative icon to outline icon when clicking outside if persistActionSelection is true', async () => {
|
|
@@ -672,10 +676,10 @@ describe('ResponseActions', () => {
|
|
|
672
676
|
);
|
|
673
677
|
|
|
674
678
|
await user.click(screen.getByRole('button', { name: 'Bad response' }));
|
|
675
|
-
expect(screen.getByText('
|
|
679
|
+
expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
|
|
676
680
|
|
|
677
681
|
await user.click(screen.getByTestId('outside'));
|
|
678
|
-
expect(screen.getByText('
|
|
682
|
+
expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
|
|
679
683
|
});
|
|
680
684
|
});
|
|
681
685
|
});
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { FunctionComponent, MouseEvent } from 'react';
|
|
2
2
|
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
RhUiLikeIcon,
|
|
5
|
+
RhUiLikeFillIcon,
|
|
6
|
+
RhUiDislikeIcon,
|
|
7
|
+
RhUiDislikeFillIcon,
|
|
8
|
+
RhUiCopyIcon,
|
|
9
|
+
RhUiCopyFillIcon,
|
|
10
|
+
RhUiEditIcon,
|
|
11
|
+
RhUiEditFillIcon,
|
|
12
|
+
RhUiVolumeUpIcon,
|
|
13
|
+
RhUiVolumeUpFillIcon,
|
|
14
|
+
RhUiExportIcon,
|
|
15
|
+
RhUiExportFillIcon
|
|
13
16
|
} from '@patternfly/react-icons';
|
|
14
17
|
import ResponseActionButton from './ResponseActionButton';
|
|
15
18
|
import { ButtonProps, TooltipProps } from '@patternfly/react-core';
|
|
@@ -164,12 +167,28 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
164
167
|
|
|
165
168
|
const iconMap = {
|
|
166
169
|
positive: {
|
|
167
|
-
filled: <
|
|
168
|
-
outlined: <
|
|
170
|
+
filled: <RhUiLikeFillIcon />,
|
|
171
|
+
outlined: <RhUiLikeIcon />
|
|
169
172
|
},
|
|
170
173
|
negative: {
|
|
171
|
-
filled: <
|
|
172
|
-
outlined: <
|
|
174
|
+
filled: <RhUiDislikeFillIcon />,
|
|
175
|
+
outlined: <RhUiDislikeIcon />
|
|
176
|
+
},
|
|
177
|
+
listen: {
|
|
178
|
+
filled: <RhUiVolumeUpFillIcon />,
|
|
179
|
+
outlined: <RhUiVolumeUpIcon />
|
|
180
|
+
},
|
|
181
|
+
copy: {
|
|
182
|
+
filled: <RhUiCopyFillIcon />,
|
|
183
|
+
outlined: <RhUiCopyIcon />
|
|
184
|
+
},
|
|
185
|
+
edit: {
|
|
186
|
+
filled: <RhUiEditFillIcon />,
|
|
187
|
+
outlined: <RhUiEditIcon />
|
|
188
|
+
},
|
|
189
|
+
download: {
|
|
190
|
+
filled: <RhUiExportFillIcon />,
|
|
191
|
+
outlined: <RhUiExportIcon />
|
|
173
192
|
}
|
|
174
193
|
};
|
|
175
194
|
|
|
@@ -247,7 +266,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
247
266
|
tooltipContent={copy.tooltipContent ?? 'Copy'}
|
|
248
267
|
clickedTooltipContent={copy.clickedTooltipContent ?? 'Copied'}
|
|
249
268
|
tooltipProps={getTooltipProps(copy.tooltipProps)}
|
|
250
|
-
icon={
|
|
269
|
+
icon={getIcon('copy')}
|
|
251
270
|
isClicked={activeButton === 'copy'}
|
|
252
271
|
ref={copy.ref}
|
|
253
272
|
aria-expanded={copy['aria-expanded']}
|
|
@@ -265,7 +284,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
265
284
|
tooltipContent={edit.tooltipContent ?? 'Edit '}
|
|
266
285
|
clickedTooltipContent={edit.clickedTooltipContent ?? 'Editing'}
|
|
267
286
|
tooltipProps={getTooltipProps(edit.tooltipProps)}
|
|
268
|
-
icon={
|
|
287
|
+
icon={getIcon('edit')}
|
|
269
288
|
isClicked={activeButton === 'edit'}
|
|
270
289
|
ref={edit.ref}
|
|
271
290
|
aria-expanded={edit['aria-expanded']}
|
|
@@ -283,7 +302,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
283
302
|
tooltipContent={share.tooltipContent ?? 'Share'}
|
|
284
303
|
clickedTooltipContent={share.clickedTooltipContent ?? 'Shared'}
|
|
285
304
|
tooltipProps={getTooltipProps(share.tooltipProps)}
|
|
286
|
-
icon={
|
|
305
|
+
icon={getIcon('download')}
|
|
287
306
|
isClicked={activeButton === 'share'}
|
|
288
307
|
ref={share.ref}
|
|
289
308
|
aria-expanded={share['aria-expanded']}
|
|
@@ -301,7 +320,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
301
320
|
tooltipContent={download.tooltipContent ?? 'Download'}
|
|
302
321
|
clickedTooltipContent={download.clickedTooltipContent ?? 'Downloaded'}
|
|
303
322
|
tooltipProps={getTooltipProps(download.tooltipProps)}
|
|
304
|
-
icon={
|
|
323
|
+
icon={getIcon('download')}
|
|
305
324
|
isClicked={activeButton === 'download'}
|
|
306
325
|
ref={download.ref}
|
|
307
326
|
aria-expanded={download['aria-expanded']}
|
|
@@ -319,7 +338,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
|
319
338
|
tooltipContent={listen.tooltipContent ?? 'Listen'}
|
|
320
339
|
clickedTooltipContent={listen.clickedTooltipContent ?? 'Listening'}
|
|
321
340
|
tooltipProps={getTooltipProps(listen.tooltipProps)}
|
|
322
|
-
icon={
|
|
341
|
+
icon={getIcon('listen')}
|
|
323
342
|
isClicked={activeButton === 'listen'}
|
|
324
343
|
ref={listen.ref}
|
|
325
344
|
aria-expanded={listen['aria-expanded']}
|