@patternfly/chatbot 2.2.0-prerelease.1 → 2.2.0-prerelease.11
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.d.ts +19 -1
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +11 -11
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +39 -3
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/CodeModal/CodeModal.js +2 -12
- package/dist/cjs/Compare/Compare.d.ts +17 -0
- package/dist/cjs/Compare/Compare.js +50 -0
- package/dist/cjs/Compare/Compare.test.d.ts +1 -0
- package/dist/cjs/Compare/Compare.test.js +20 -0
- package/dist/cjs/Compare/index.d.ts +2 -0
- package/dist/cjs/Compare/index.js +23 -0
- package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
- package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
- package/dist/cjs/Message/Message.d.ts +16 -6
- package/dist/cjs/Message/Message.js +6 -6
- package/dist/cjs/Message/Message.test.js +51 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +15 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.js +33 -0
- package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
- package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
- package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
- package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
- package/dist/cjs/Message/QuickStarts/types.js +17 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
- package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
- package/dist/cjs/Settings/SettingsForm.js +27 -0
- package/dist/cjs/Settings/index.d.ts +2 -0
- package/dist/cjs/Settings/index.js +23 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +34 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.js +49 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.test.d.ts +1 -0
- package/dist/cjs/TermsOfUse/TermsOfUse.test.js +79 -0
- package/dist/cjs/TermsOfUse/index.d.ts +2 -0
- package/dist/cjs/TermsOfUse/index.js +23 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +10 -1
- package/dist/css/main.css +244 -18
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/Compare/package.json +1 -0
- package/dist/dynamic/Settings/package.json +1 -0
- package/dist/dynamic/TermsOfUse/package.json +1 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +19 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +11 -11
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +39 -3
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/CodeModal/CodeModal.js +2 -12
- package/dist/esm/Compare/Compare.d.ts +17 -0
- package/dist/esm/Compare/Compare.js +43 -0
- package/dist/esm/Compare/Compare.test.d.ts +1 -0
- package/dist/esm/Compare/Compare.test.js +15 -0
- package/dist/esm/Compare/index.d.ts +2 -0
- package/dist/esm/Compare/index.js +2 -0
- package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
- package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
- package/dist/esm/Message/Message.d.ts +16 -6
- package/dist/esm/Message/Message.js +7 -7
- package/dist/esm/Message/Message.test.js +51 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +15 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.js +26 -0
- package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
- package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
- package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
- package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
- package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
- package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
- package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
- package/dist/esm/Message/QuickStarts/types.js +14 -0
- package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
- package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
- package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
- package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
- package/dist/esm/ResponseActions/ResponseActions.js +26 -9
- package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
- package/dist/esm/Settings/SettingsForm.d.ts +13 -0
- package/dist/esm/Settings/SettingsForm.js +20 -0
- package/dist/esm/Settings/index.d.ts +2 -0
- package/dist/esm/Settings/index.js +2 -0
- package/dist/esm/TermsOfUse/TermsOfUse.d.ts +34 -0
- package/dist/esm/TermsOfUse/TermsOfUse.js +42 -0
- package/dist/esm/TermsOfUse/TermsOfUse.test.d.ts +1 -0
- package/dist/esm/TermsOfUse/TermsOfUse.test.js +74 -0
- package/dist/esm/TermsOfUse/index.d.ts +2 -0
- package/dist/esm/TermsOfUse/index.js +2 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +6 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -13
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +26 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerNavigation.tsx +67 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerResizable.tsx +94 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +78 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/PF-TermsAndConditionsHeader.svg +148 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUse.tsx +147 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +54 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +26 -3
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +20 -19
- package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +2 -2
- package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx +206 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +112 -3
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +46 -9
- package/src/ChatbotFooter/ChatbotFooter.scss +2 -1
- package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/CodeModal/CodeModal.scss +8 -0
- package/src/CodeModal/CodeModal.tsx +2 -13
- package/src/Compare/Compare.scss +72 -0
- package/src/Compare/Compare.test.tsx +31 -0
- package/src/Compare/Compare.tsx +98 -0
- package/src/Compare/index.ts +2 -0
- package/src/FileDropZone/__snapshots__/FileDropZone.test.tsx.snap +1 -1
- package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
- package/src/Message/Message.scss +0 -14
- package/src/Message/Message.test.tsx +76 -0
- package/src/Message/Message.tsx +35 -26
- package/src/Message/QuickResponse/QuickResponse.scss +33 -0
- package/src/Message/QuickResponse/QuickResponse.tsx +50 -0
- package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
- package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
- package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
- package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
- package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
- package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
- package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
- package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
- package/src/Message/QuickStarts/types.ts +154 -0
- package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
- package/src/ResponseActions/ResponseActionButton.tsx +46 -27
- package/src/ResponseActions/ResponseActions.scss +10 -8
- package/src/ResponseActions/ResponseActions.test.tsx +103 -5
- package/src/ResponseActions/ResponseActions.tsx +54 -7
- package/src/Settings/Settings.scss +34 -0
- package/src/Settings/SettingsForm.tsx +25 -0
- package/src/Settings/index.ts +3 -0
- package/src/TermsOfUse/TermsOfUse.scss +66 -0
- package/src/TermsOfUse/TermsOfUse.test.tsx +138 -0
- package/src/TermsOfUse/TermsOfUse.tsx +117 -0
- package/src/TermsOfUse/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/main.scss +5 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
.pf-chatbot__compare-container {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
4
|
+
position: relative;
|
5
|
+
height: 100%;
|
6
|
+
}
|
7
|
+
.pf-chatbot__compare-toggle {
|
8
|
+
width: 100%;
|
9
|
+
|
10
|
+
.pf-v6-c-toggle-group__button {
|
11
|
+
width: 100%;
|
12
|
+
display: flex;
|
13
|
+
justify-content: center;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
.pf-chatbot__compare {
|
17
|
+
display: flex;
|
18
|
+
height: 100%;
|
19
|
+
width: 100%;
|
20
|
+
|
21
|
+
@media screen and (max-width: 900px) {
|
22
|
+
overflow-y: auto;
|
23
|
+
}
|
24
|
+
|
25
|
+
.pf-chatbot__compare-item:first-of-type {
|
26
|
+
border-right: 1px solid var(--pf-t--global--border--color--default);
|
27
|
+
|
28
|
+
@media screen and (max-width: 900px) {
|
29
|
+
border-right: 0px;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
.pf-chatbot__compare-item {
|
35
|
+
flex: 1;
|
36
|
+
|
37
|
+
.pf-chatbot--embedded .pf-chatbot__messagebox {
|
38
|
+
width: 100%;
|
39
|
+
}
|
40
|
+
|
41
|
+
.pf-chatbot__content {
|
42
|
+
padding: 0;
|
43
|
+
}
|
44
|
+
|
45
|
+
.pf-chatbot.pf-chatbot--embedded {
|
46
|
+
@media screen and (max-width: 900px) {
|
47
|
+
height: 100%;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
.pf-chatbot__compare-item-hidden {
|
52
|
+
display: block;
|
53
|
+
|
54
|
+
@media screen and (max-width: 900px) {
|
55
|
+
display: none;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
.pf-chatbot__compare-mobile-controls {
|
60
|
+
padding: var(--pf-t--global--spacer--md) var(--pf-t--global--spacer--lg) 0 var(--pf-t--global--spacer--lg);
|
61
|
+
display: none;
|
62
|
+
background-color: var(--pf-t--global--background--color--secondary--default);
|
63
|
+
position: sticky;
|
64
|
+
top: 0;
|
65
|
+
z-index: 9999;
|
66
|
+
|
67
|
+
@media screen and (max-width: 900px) {
|
68
|
+
display: flex;
|
69
|
+
flex-direction: column;
|
70
|
+
gap: var(--pf-t--global--spacer--md);
|
71
|
+
}
|
72
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { render, screen } from '@testing-library/react';
|
3
|
+
import '@testing-library/jest-dom';
|
4
|
+
import Compare from './Compare';
|
5
|
+
|
6
|
+
const firstChild = (
|
7
|
+
<div>
|
8
|
+
<h1>Child 1</h1>
|
9
|
+
</div>
|
10
|
+
);
|
11
|
+
|
12
|
+
const secondChild = (
|
13
|
+
<div>
|
14
|
+
<h1>Child 2</h1>
|
15
|
+
</div>
|
16
|
+
);
|
17
|
+
|
18
|
+
describe('Compare', () => {
|
19
|
+
it('should render compare correctly', () => {
|
20
|
+
render(
|
21
|
+
<Compare
|
22
|
+
firstChildDisplayName="Child 1"
|
23
|
+
secondChildDisplayName="Child 2"
|
24
|
+
firstChild={firstChild}
|
25
|
+
secondChild={secondChild}
|
26
|
+
/>
|
27
|
+
);
|
28
|
+
expect(screen.getByRole('heading', { name: /Child 1/i })).toBeTruthy();
|
29
|
+
expect(screen.getByRole('heading', { name: /Child 2/i })).toBeTruthy();
|
30
|
+
});
|
31
|
+
});
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
2
|
+
import { ToggleGroup, ToggleGroupItem } from '@patternfly/react-core';
|
3
|
+
|
4
|
+
interface CompareProps {
|
5
|
+
/** First of two children to render */
|
6
|
+
firstChild: React.ReactNode;
|
7
|
+
/** Second of two children to render */
|
8
|
+
secondChild: React.ReactNode;
|
9
|
+
/** Display name for first child, used in mobile toggle */
|
10
|
+
firstChildDisplayName: string;
|
11
|
+
/** Display name for second child, used in mobile toggle */
|
12
|
+
secondChildDisplayName: string;
|
13
|
+
/** Aria label for mobile toggle group */
|
14
|
+
toggleGroupAriaLabel?: string;
|
15
|
+
/** Callback for when mobile toggle is used */
|
16
|
+
onToggleClick?: (event: MouseEvent | React.MouseEvent<any, MouseEvent> | React.KeyboardEvent<Element>) => void;
|
17
|
+
}
|
18
|
+
|
19
|
+
export const Compare = ({
|
20
|
+
firstChild,
|
21
|
+
secondChild,
|
22
|
+
firstChildDisplayName,
|
23
|
+
secondChildDisplayName,
|
24
|
+
onToggleClick,
|
25
|
+
toggleGroupAriaLabel = 'Select which chatbot to display'
|
26
|
+
}: PropsWithChildren<CompareProps>) => {
|
27
|
+
const [isSelected, setIsSelected] = React.useState('toggle-group-chatbot-1');
|
28
|
+
const [showFirstChatbot, setShowFirstChatbot] = React.useState(true);
|
29
|
+
const [showSecondChatbot, setShowSecondChatbot] = React.useState(false);
|
30
|
+
|
31
|
+
React.useEffect(() => {
|
32
|
+
// we want to show the first if we switch to the mobile toggle view
|
33
|
+
// and reset/switch back to normal otherwise
|
34
|
+
const updateChatbotVisibility = () => {
|
35
|
+
if (window.innerWidth >= 901) {
|
36
|
+
setShowFirstChatbot(true);
|
37
|
+
setShowSecondChatbot(true);
|
38
|
+
} else {
|
39
|
+
setShowFirstChatbot(true);
|
40
|
+
setShowSecondChatbot(false);
|
41
|
+
setIsSelected('toggle-group-chatbot-1');
|
42
|
+
}
|
43
|
+
};
|
44
|
+
window.addEventListener('resize', updateChatbotVisibility);
|
45
|
+
|
46
|
+
return () => {
|
47
|
+
window.removeEventListener('resize', updateChatbotVisibility);
|
48
|
+
};
|
49
|
+
}, []);
|
50
|
+
|
51
|
+
// this only happens on mobile
|
52
|
+
const handleChildToggleClick = (
|
53
|
+
event: MouseEvent | React.MouseEvent<any, MouseEvent> | React.KeyboardEvent<Element>
|
54
|
+
) => {
|
55
|
+
const id = event.currentTarget.id;
|
56
|
+
setIsSelected(id);
|
57
|
+
setShowSecondChatbot(!showSecondChatbot);
|
58
|
+
setShowFirstChatbot(!showFirstChatbot);
|
59
|
+
onToggleClick && onToggleClick(event);
|
60
|
+
};
|
61
|
+
|
62
|
+
return (
|
63
|
+
<>
|
64
|
+
<div className="pf-chatbot__compare-mobile-controls">
|
65
|
+
<ToggleGroup aria-label={toggleGroupAriaLabel}>
|
66
|
+
<ToggleGroupItem
|
67
|
+
className="pf-chatbot__compare-toggle"
|
68
|
+
text={firstChildDisplayName}
|
69
|
+
buttonId="toggle-group-chatbot-1"
|
70
|
+
isSelected={isSelected === 'toggle-group-chatbot-1'}
|
71
|
+
onChange={handleChildToggleClick}
|
72
|
+
/>
|
73
|
+
<ToggleGroupItem
|
74
|
+
className="pf-chatbot__compare-toggle"
|
75
|
+
text={secondChildDisplayName}
|
76
|
+
buttonId="toggle-group-chatbot-2"
|
77
|
+
isSelected={isSelected === 'toggle-group-chatbot-2'}
|
78
|
+
onChange={handleChildToggleClick}
|
79
|
+
/>
|
80
|
+
</ToggleGroup>
|
81
|
+
</div>
|
82
|
+
<div className="pf-chatbot__compare">
|
83
|
+
<div
|
84
|
+
className={`pf-chatbot__compare-item ${!showFirstChatbot ? 'pf-chatbot__compare-item-hidden' : undefined}`}
|
85
|
+
>
|
86
|
+
{firstChild}
|
87
|
+
</div>
|
88
|
+
<div
|
89
|
+
className={`pf-chatbot__compare-item ${!showSecondChatbot ? 'pf-chatbot__compare-item-hidden' : undefined}`}
|
90
|
+
>
|
91
|
+
{secondChild}
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
</>
|
95
|
+
);
|
96
|
+
};
|
97
|
+
|
98
|
+
export default Compare;
|
@@ -9,7 +9,7 @@ exports[`FileDropZone should render file drop zone 1`] = `
|
|
9
9
|
>
|
10
10
|
<input
|
11
11
|
multiple=""
|
12
|
-
style="
|
12
|
+
style="border: 0px; clip: rect(0px, 0px, 0px, 0px); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
|
13
13
|
tabindex="-1"
|
14
14
|
type="file"
|
15
15
|
/>
|
@@ -6,9 +6,9 @@ import React from 'react';
|
|
6
6
|
import { ExtraProps } from 'react-markdown';
|
7
7
|
import { List, ListComponent, OrderType } from '@patternfly/react-core';
|
8
8
|
|
9
|
-
const OrderedListMessage = ({ children }: JSX.IntrinsicElements['ol'] & ExtraProps) => (
|
9
|
+
const OrderedListMessage = ({ children, start }: JSX.IntrinsicElements['ol'] & ExtraProps) => (
|
10
10
|
<div className="pf-chatbot__message-ordered-list">
|
11
|
-
<List component={ListComponent.ol} type={OrderType.number}>
|
11
|
+
<List component={ListComponent.ol} type={OrderType.number} start={start}>
|
12
12
|
{children}
|
13
13
|
</List>
|
14
14
|
</div>
|
package/src/Message/Message.scss
CHANGED
@@ -95,20 +95,6 @@
|
|
95
95
|
display: grid;
|
96
96
|
gap: var(--pf-t--global--spacer--sm);
|
97
97
|
}
|
98
|
-
|
99
|
-
&-quick-response {
|
100
|
-
.pf-v6-c-label {
|
101
|
-
--pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);
|
102
|
-
|
103
|
-
@media screen and (min-width: 401px) and (max-width: 600px) {
|
104
|
-
--pf-v6-c-label__text--MaxWidth: 20ch;
|
105
|
-
}
|
106
|
-
|
107
|
-
@media screen and (max-width: 400px) {
|
108
|
-
--pf-v6-c-label__text--MaxWidth: 15ch;
|
109
|
-
}
|
110
|
-
}
|
111
|
-
}
|
112
98
|
}
|
113
99
|
|
114
100
|
// Attachments
|
@@ -3,6 +3,8 @@ import { render, screen } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom';
|
4
4
|
import Message from './Message';
|
5
5
|
import userEvent from '@testing-library/user-event';
|
6
|
+
import { monitorSampleAppQuickStart } from './QuickStarts/monitor-sampleapp-quickstart';
|
7
|
+
import { monitorSampleAppQuickStartWithImage } from './QuickStarts/monitor-sampleapp-quickstart-with-image';
|
6
8
|
|
7
9
|
const ALL_ACTIONS = [
|
8
10
|
{ label: /Good response/i },
|
@@ -53,6 +55,22 @@ spec:
|
|
53
55
|
|
54
56
|
const INLINE_CODE = `Here is an inline code - \`() => void\``;
|
55
57
|
|
58
|
+
const ORDERED_LIST_WITH_CODE = `
|
59
|
+
1. Item 1
|
60
|
+
2. Item 2
|
61
|
+
|
62
|
+
\`\`\`yaml
|
63
|
+
- name: Hello World Playbook
|
64
|
+
hosts: localhost
|
65
|
+
tasks:
|
66
|
+
- name: Print Hello World
|
67
|
+
ansible.builtin.debug:
|
68
|
+
msg: "Hello, World!"
|
69
|
+
\`\`\`
|
70
|
+
|
71
|
+
3. Item 3
|
72
|
+
`;
|
73
|
+
|
56
74
|
const checkListItemsRendered = () => {
|
57
75
|
const items = ['Item 1', 'Item 2', 'Item 3'];
|
58
76
|
expect(screen.getAllByRole('listitem')).toHaveLength(3);
|
@@ -344,6 +362,12 @@ describe('Message', () => {
|
|
344
362
|
expect(screen.getByText('Here is an ordered list:')).toBeTruthy();
|
345
363
|
checkListItemsRendered();
|
346
364
|
});
|
365
|
+
it('should render ordered lists correctly if there is interstitial content', () => {
|
366
|
+
render(<Message avatar="./img" role="user" name="User" content={ORDERED_LIST_WITH_CODE} />);
|
367
|
+
checkListItemsRendered();
|
368
|
+
const list = screen.getAllByRole('list')[1];
|
369
|
+
expect(list).toHaveAttribute('start', '3');
|
370
|
+
});
|
347
371
|
it('should render inline code', () => {
|
348
372
|
render(<Message avatar="./img" role="user" name="User" content={INLINE_CODE} />);
|
349
373
|
expect(screen.getByText(/() => void/i)).toBeTruthy();
|
@@ -415,4 +439,56 @@ describe('Message', () => {
|
|
415
439
|
expect(screen.getByRole('img')).toHaveClass('test');
|
416
440
|
expect(screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
|
417
441
|
});
|
442
|
+
it('should handle QuickStart tile correctly', () => {
|
443
|
+
render(
|
444
|
+
<Message
|
445
|
+
avatar="./img"
|
446
|
+
role="user"
|
447
|
+
name="User"
|
448
|
+
content="Hi"
|
449
|
+
quickStarts={{
|
450
|
+
quickStart: monitorSampleAppQuickStart,
|
451
|
+
onSelectQuickStart: (id) => alert(id)
|
452
|
+
}}
|
453
|
+
/>
|
454
|
+
);
|
455
|
+
expect(screen.getByRole('button', { name: 'Monitoring your sample application' })).toBeTruthy();
|
456
|
+
expect(screen.getByRole('heading', { name: '1 Prerequisite' })).toBeTruthy();
|
457
|
+
expect(screen.getByRole('button', { name: 'Show prerequisites' })).toBeTruthy();
|
458
|
+
expect(screen.getByRole('button', { name: 'Start' })).toBeTruthy();
|
459
|
+
});
|
460
|
+
it('should handle click on QuickStart tile correctly', async () => {
|
461
|
+
const spy = jest.fn();
|
462
|
+
render(
|
463
|
+
<Message
|
464
|
+
avatar="./img"
|
465
|
+
role="user"
|
466
|
+
name="User"
|
467
|
+
content="Hi"
|
468
|
+
quickStarts={{
|
469
|
+
quickStart: monitorSampleAppQuickStart,
|
470
|
+
onSelectQuickStart: (id) => spy(id)
|
471
|
+
}}
|
472
|
+
/>
|
473
|
+
);
|
474
|
+
await userEvent.click(screen.getByRole('button', { name: 'Monitoring your sample application' }));
|
475
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
476
|
+
expect(spy).toHaveBeenCalledWith(monitorSampleAppQuickStart.metadata.name);
|
477
|
+
});
|
478
|
+
it('should handle QuickStart tile with image correctly', async () => {
|
479
|
+
const spy = jest.fn();
|
480
|
+
render(
|
481
|
+
<Message
|
482
|
+
avatar="./img"
|
483
|
+
role="user"
|
484
|
+
name="User"
|
485
|
+
content="Hi"
|
486
|
+
quickStarts={{
|
487
|
+
quickStart: monitorSampleAppQuickStartWithImage,
|
488
|
+
onSelectQuickStart: (id) => spy(id)
|
489
|
+
}}
|
490
|
+
/>
|
491
|
+
);
|
492
|
+
expect(screen.getAllByRole('img')[1]).toHaveAttribute('src', 'test.png');
|
493
|
+
});
|
418
494
|
});
|
package/src/Message/Message.tsx
CHANGED
@@ -6,16 +6,7 @@ import React from 'react';
|
|
6
6
|
|
7
7
|
import Markdown from 'react-markdown';
|
8
8
|
import remarkGfm from 'remark-gfm';
|
9
|
-
import {
|
10
|
-
Avatar,
|
11
|
-
AvatarProps,
|
12
|
-
Label,
|
13
|
-
LabelGroup,
|
14
|
-
LabelGroupProps,
|
15
|
-
LabelProps,
|
16
|
-
Timestamp,
|
17
|
-
Truncate
|
18
|
-
} from '@patternfly/react-core';
|
9
|
+
import { Avatar, AvatarProps, Label, LabelGroupProps, Timestamp, Truncate } from '@patternfly/react-core';
|
19
10
|
import MessageLoading from './MessageLoading';
|
20
11
|
import CodeBlockMessage from './CodeBlockMessage/CodeBlockMessage';
|
21
12
|
import TextMessage from './TextMessage/TextMessage';
|
@@ -25,12 +16,10 @@ import SourcesCard, { SourcesCardProps } from '../SourcesCard';
|
|
25
16
|
import ListItemMessage from './ListMessage/ListItemMessage';
|
26
17
|
import UnorderedListMessage from './ListMessage/UnorderedListMessage';
|
27
18
|
import OrderedListMessage from './ListMessage/OrderedListMessage';
|
19
|
+
import QuickStartTile from './QuickStarts/QuickStartTile';
|
20
|
+
import { QuickStart, QuickstartAction } from './QuickStarts/types';
|
21
|
+
import QuickResponse from './QuickResponse/QuickResponse';
|
28
22
|
|
29
|
-
export interface QuickResponse extends Omit<LabelProps, 'children'> {
|
30
|
-
content: string;
|
31
|
-
id: string;
|
32
|
-
onClick: () => void;
|
33
|
-
}
|
34
23
|
export interface MessageAttachment {
|
35
24
|
/** Name of file attached to the message */
|
36
25
|
name: string;
|
@@ -89,6 +78,19 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
|
|
89
78
|
hasRoundAvatar?: boolean;
|
90
79
|
/** Any additional props applied to the avatar, for additional customization */
|
91
80
|
avatarProps?: Omit<AvatarProps, 'alt'>;
|
81
|
+
/** Props for QuickStart card */
|
82
|
+
quickStarts?: {
|
83
|
+
quickStart: QuickStart;
|
84
|
+
onSelectQuickStart: (id?: string) => void;
|
85
|
+
minuteWord?: string;
|
86
|
+
minuteWordPlural?: string;
|
87
|
+
prerequisiteWord?: string;
|
88
|
+
prerequisiteWordPlural?: string;
|
89
|
+
quickStartButtonAriaLabel?: string;
|
90
|
+
className?: string;
|
91
|
+
onClick?: () => void;
|
92
|
+
action?: QuickstartAction;
|
93
|
+
};
|
92
94
|
}
|
93
95
|
|
94
96
|
export const Message: React.FunctionComponent<MessageProps> = ({
|
@@ -108,6 +110,7 @@ export const Message: React.FunctionComponent<MessageProps> = ({
|
|
108
110
|
attachments,
|
109
111
|
hasRoundAvatar = true,
|
110
112
|
avatarProps,
|
113
|
+
quickStarts,
|
111
114
|
...props
|
112
115
|
}: MessageProps) => {
|
113
116
|
let avatarClassName;
|
@@ -119,6 +122,7 @@ export const Message: React.FunctionComponent<MessageProps> = ({
|
|
119
122
|
// Keep timestamps consistent between Timestamp component and aria-label
|
120
123
|
const date = new Date();
|
121
124
|
const dateString = timestamp ?? `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
125
|
+
|
122
126
|
return (
|
123
127
|
<section
|
124
128
|
aria-label={`Message from ${role} - ${dateString}`}
|
@@ -156,7 +160,7 @@ export const Message: React.FunctionComponent<MessageProps> = ({
|
|
156
160
|
p: TextMessage,
|
157
161
|
code: ({ children }) => <CodeBlockMessage {...codeBlockProps}>{children}</CodeBlockMessage>,
|
158
162
|
ul: UnorderedListMessage,
|
159
|
-
ol: OrderedListMessage
|
163
|
+
ol: (props) => <OrderedListMessage {...props} />,
|
160
164
|
li: ListItemMessage
|
161
165
|
}}
|
162
166
|
remarkPlugins={[remarkGfm]}
|
@@ -165,18 +169,23 @@ export const Message: React.FunctionComponent<MessageProps> = ({
|
|
165
169
|
</Markdown>
|
166
170
|
)}
|
167
171
|
{!isLoading && sources && <SourcesCard {...sources} />}
|
172
|
+
{quickStarts && quickStarts.quickStart && (
|
173
|
+
<QuickStartTile
|
174
|
+
quickStart={quickStarts.quickStart}
|
175
|
+
onSelectQuickStart={quickStarts.onSelectQuickStart}
|
176
|
+
minuteWord={quickStarts.minuteWord}
|
177
|
+
minuteWordPlural={quickStarts.minuteWordPlural}
|
178
|
+
prerequisiteWord={quickStarts.prerequisiteWord}
|
179
|
+
prerequisiteWordPlural={quickStarts.prerequisiteWordPlural}
|
180
|
+
quickStartButtonAriaLabel={quickStarts.quickStartButtonAriaLabel}
|
181
|
+
/>
|
182
|
+
)}
|
168
183
|
{!isLoading && actions && <ResponseActions actions={actions} />}
|
169
184
|
{!isLoading && quickResponses && (
|
170
|
-
<
|
171
|
-
|
172
|
-
{
|
173
|
-
|
174
|
-
{quickResponses.map(({ id, onClick, content, ...props }: QuickResponse) => (
|
175
|
-
<Label variant="outline" color="blue" key={id} onClick={onClick} {...props}>
|
176
|
-
{content}
|
177
|
-
</Label>
|
178
|
-
))}
|
179
|
-
</LabelGroup>
|
185
|
+
<QuickResponse
|
186
|
+
quickResponses={quickResponses}
|
187
|
+
quickResponseContainerProps={quickResponseContainerProps}
|
188
|
+
/>
|
180
189
|
)}
|
181
190
|
</div>
|
182
191
|
{attachments && (
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.pf-chatbot__message-quick-response {
|
2
|
+
.pf-v6-c-label {
|
3
|
+
--pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);
|
4
|
+
|
5
|
+
@media screen and (min-width: 401px) and (max-width: 600px) {
|
6
|
+
--pf-v6-c-label__text--MaxWidth: 20ch;
|
7
|
+
}
|
8
|
+
|
9
|
+
@media screen and (max-width: 400px) {
|
10
|
+
--pf-v6-c-label__text--MaxWidth: 15ch;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
.pf-chatbot__message-quick-response--selected {
|
15
|
+
.pf-v6-c-label__content:is(:hover, :focus) {
|
16
|
+
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
|
17
|
+
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
.pf-chatbot__message-quick-response--selected:hover,
|
22
|
+
.pf-chatbot__message-quick-response--selected:focus {
|
23
|
+
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
|
24
|
+
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
|
25
|
+
}
|
26
|
+
|
27
|
+
// active state right before selection
|
28
|
+
.pf-v6-c-label.pf-m-blue.pf-m-clickable .pf-v6-c-label__content:is(:active) {
|
29
|
+
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
|
30
|
+
--pf-v6-c-label--m-clickable--hover--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
|
31
|
+
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Label, LabelGroup, LabelGroupProps, LabelProps } from '@patternfly/react-core';
|
3
|
+
import { CheckIcon } from '@patternfly/react-icons';
|
4
|
+
|
5
|
+
export interface QuickResponse extends Omit<LabelProps, 'children'> {
|
6
|
+
content: string;
|
7
|
+
id: string;
|
8
|
+
onClick: () => void;
|
9
|
+
}
|
10
|
+
|
11
|
+
export interface QuickResponseProps {
|
12
|
+
/** Props for quick responses */
|
13
|
+
quickResponses: QuickResponse[];
|
14
|
+
/** Props for quick responses container */
|
15
|
+
quickResponseContainerProps?: Omit<LabelGroupProps, 'ref'>;
|
16
|
+
}
|
17
|
+
|
18
|
+
export const QuickResponse: React.FunctionComponent<QuickResponseProps> = ({
|
19
|
+
quickResponses,
|
20
|
+
quickResponseContainerProps = { numLabels: 5 }
|
21
|
+
}: QuickResponseProps) => {
|
22
|
+
const [selectedQuickResponse, setSelectedQuickResponse] = React.useState<string>();
|
23
|
+
|
24
|
+
const handleQuickResponseClick = (id: string, onClick?: () => void) => {
|
25
|
+
setSelectedQuickResponse(id);
|
26
|
+
onClick && onClick();
|
27
|
+
};
|
28
|
+
return (
|
29
|
+
<LabelGroup
|
30
|
+
className={`pf-chatbot__message-quick-response ${quickResponseContainerProps?.className}`}
|
31
|
+
{...quickResponseContainerProps}
|
32
|
+
>
|
33
|
+
{quickResponses.map(({ id, onClick, content, className, ...props }: QuickResponse) => (
|
34
|
+
<Label
|
35
|
+
variant={id === selectedQuickResponse ? undefined : 'outline'}
|
36
|
+
icon={id === selectedQuickResponse ? <CheckIcon /> : undefined}
|
37
|
+
color="blue"
|
38
|
+
key={id}
|
39
|
+
onClick={() => handleQuickResponseClick(id, onClick)}
|
40
|
+
className={`${id === selectedQuickResponse ? 'pf-chatbot__message-quick-response--selected' : ''} ${className ? className : ''}`}
|
41
|
+
{...props}
|
42
|
+
>
|
43
|
+
{content}
|
44
|
+
</Label>
|
45
|
+
))}
|
46
|
+
</LabelGroup>
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
export default QuickResponse;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
|
3
|
+
interface FallbackImgProps {
|
4
|
+
/** Image source */
|
5
|
+
src: string;
|
6
|
+
/** Alt text for image */
|
7
|
+
alt?: string;
|
8
|
+
/** ClassName applied to image */
|
9
|
+
className?: string;
|
10
|
+
/** Fallback */
|
11
|
+
fallback?: React.ReactNode;
|
12
|
+
}
|
13
|
+
|
14
|
+
const FallbackImg: React.FC<FallbackImgProps> = ({ src, alt, className, fallback }) => {
|
15
|
+
const [isSrcValid, setIsSrcValid] = React.useState<boolean>(true);
|
16
|
+
|
17
|
+
if (src && isSrcValid) {
|
18
|
+
return <img className={className} src={src} alt={alt} onError={() => setIsSrcValid(false)} />;
|
19
|
+
}
|
20
|
+
|
21
|
+
return <>{fallback}</>;
|
22
|
+
};
|
23
|
+
|
24
|
+
export default FallbackImg;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
.pf-chatbot__quickstarts-tile {
|
2
|
+
min-width: 360px;
|
3
|
+
max-width: 650px;
|
4
|
+
width: 100%;
|
5
|
+
|
6
|
+
@media screen and (max-width: 700px) {
|
7
|
+
max-width: 100%;
|
8
|
+
min-width: initial;
|
9
|
+
}
|
10
|
+
// some icons provided to catalog tiles might have no defined height/width. Without this style, in those cases
|
11
|
+
// the icons would have a height and width of 0.
|
12
|
+
.pf-v6-c-card__header-main {
|
13
|
+
.pf-v6-c-icon__content {
|
14
|
+
display: contents;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
.pf-v6-theme-dark {
|
20
|
+
.pf-chatbot__quickstarts-tile {
|
21
|
+
.pfext-catalog-item-icon__img {
|
22
|
+
filter: brightness(1.5) invert(1) hue-rotate(180deg) saturate(4);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|